diff options
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google')
26 files changed, 43268 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile new file mode 100755 index 0000000..0d4f84e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/Rakefile @@ -0,0 +1,3 @@ +import '../../../lib/google/tasks/ffi.rake' + +task default: ['ffi-protobuf:default']
\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c new file mode 100755 index 0000000..d2b7094 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.c @@ -0,0 +1,335 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby <-> upb data conversion functions. +// +// This file Also contains a few other assorted algorithms on upb_MessageValue. +// +// None of the algorithms in this file require any access to the internal +// representation of Ruby or upb objects. +// ----------------------------------------------------------------------------- + +#include "convert.h" + +#include "message.h" +#include "protobuf.h" +#include "shared_convert.h" + +static upb_StringView Convert_StringData(VALUE str, upb_Arena* arena) { + upb_StringView ret; + if (arena) { + char* ptr = upb_Arena_Malloc(arena, RSTRING_LEN(str)); + memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str)); + ret.data = ptr; + } else { + // Data is only needed temporarily (within map lookup). + ret.data = RSTRING_PTR(str); + } + ret.size = RSTRING_LEN(str); + return ret; +} + +static bool is_ruby_num(VALUE value) { + return (TYPE(value) == T_FLOAT || TYPE(value) == T_FIXNUM || + TYPE(value) == T_BIGNUM); +} + +static void Convert_CheckInt(const char* name, upb_CType type, VALUE val) { + if (!is_ruby_num(val)) { + rb_raise(cTypeError, + "Expected number type for integral field '%s' (given %s).", name, + rb_class2name(CLASS_OF(val))); + } + + // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper + // bound; we just need to do precision checks (i.e., disallow rounding) and + // check for < 0 on unsigned types. + if (TYPE(val) == T_FLOAT) { + double dbl_val = NUM2DBL(val); + if (floor(dbl_val) != dbl_val) { + rb_raise(rb_eRangeError, + "Non-integral floating point value assigned to integer field " + "'%s' (given %s).", + name, rb_class2name(CLASS_OF(val))); + } + } + if (type == kUpb_CType_UInt32 || type == kUpb_CType_UInt64) { + if (NUM2DBL(val) < 0) { + rb_raise( + rb_eRangeError, + "Assigning negative value to unsigned integer field '%s' (given %s).", + name, rb_class2name(CLASS_OF(val))); + } + } +} + +static int32_t Convert_ToEnum(VALUE value, const char* name, + const upb_EnumDef* e) { + int32_t val; + + switch (TYPE(value)) { + case T_FLOAT: + case T_FIXNUM: + case T_BIGNUM: + Convert_CheckInt(name, kUpb_CType_Int32, value); + val = NUM2INT(value); + break; + case T_STRING: { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize( + e, RSTRING_PTR(value), RSTRING_LEN(value)); + if (!ev) goto unknownval; + val = upb_EnumValueDef_Number(ev); + break; + } + case T_SYMBOL: { + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByName(e, rb_id2name(SYM2ID(value))); + if (!ev) goto unknownval; + val = upb_EnumValueDef_Number(ev); + break; + } + default: + rb_raise(cTypeError, + "Expected number or symbol type for enum field '%s'.", name); + } + + return val; + +unknownval: + rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name); +} + +VALUE Convert_CheckStringUtf8(VALUE str) { + VALUE utf8 = rb_enc_from_encoding(rb_utf8_encoding()); + + if (rb_obj_encoding(str) == utf8) { + // Note: Just because a string is marked as having UTF-8 encoding does + // not mean that it is *valid* UTF-8. We have to check separately + // whether it is valid. + if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) { + VALUE exc = rb_const_get_at( + rb_cEncoding, rb_intern("InvalidByteSequenceError")); + rb_raise(exc, "String is invalid UTF-8"); + } + } else { + // Note: this will not duplicate underlying string data unless + // necessary. + // + // This will throw an exception if the conversion cannot be performed: + // - Encoding::UndefinedConversionError if certain characters cannot be + // converted to UTF-8. + // - Encoding::InvalidByteSequenceError if certain characters were invalid + // in the source encoding. + str = rb_str_encode(str, utf8, 0, Qnil); + PBRUBY_ASSERT(rb_enc_str_coderange(str) != ENC_CODERANGE_BROKEN); + } + + return str; +} + +upb_MessageValue Convert_RubyToUpb(VALUE value, const char* name, + TypeInfo type_info, upb_Arena* arena) { + upb_MessageValue ret; + + switch (type_info.type) { + case kUpb_CType_Float: + if (!is_ruby_num(value)) { + rb_raise(cTypeError, + "Expected number type for float field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + ret.float_val = NUM2DBL(value); + break; + case kUpb_CType_Double: + if (!is_ruby_num(value)) { + rb_raise(cTypeError, + "Expected number type for double field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + ret.double_val = NUM2DBL(value); + break; + case kUpb_CType_Bool: { + if (value == Qtrue) { + ret.bool_val = 1; + } else if (value == Qfalse) { + ret.bool_val = 0; + } else { + rb_raise(cTypeError, + "Invalid argument for boolean field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + break; + } + case kUpb_CType_String: + if (rb_obj_class(value) == rb_cSymbol) { + value = rb_funcall(value, rb_intern("to_s"), 0); + } else if (!rb_obj_is_kind_of(value, rb_cString)) { + rb_raise(cTypeError, + "Invalid argument for string field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + + value = Convert_CheckStringUtf8(value); + ret.str_val = Convert_StringData(value, arena); + break; + case kUpb_CType_Bytes: { + VALUE bytes = rb_enc_from_encoding(rb_ascii8bit_encoding()); + if (rb_obj_class(value) != rb_cString) { + rb_raise(cTypeError, + "Invalid argument for bytes field '%s' (given %s).", name, + rb_class2name(CLASS_OF(value))); + } + + if (rb_obj_encoding(value) != bytes) { + // Note: this will not duplicate underlying string data unless + // necessary. + // TODO: is this really necessary to get raw bytes? + value = rb_str_encode(value, bytes, 0, Qnil); + } + + ret.str_val = Convert_StringData(value, arena); + break; + } + case kUpb_CType_Message: + ret.msg_val = + Message_GetUpbMessage(value, type_info.def.msgdef, name, arena); + break; + case kUpb_CType_Enum: + ret.int32_val = Convert_ToEnum(value, name, type_info.def.enumdef); + break; + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + Convert_CheckInt(name, type_info.type, value); + switch (type_info.type) { + case kUpb_CType_Int32: + ret.int32_val = NUM2INT(value); + break; + case kUpb_CType_Int64: + ret.int64_val = NUM2LL(value); + break; + case kUpb_CType_UInt32: + ret.uint32_val = NUM2UINT(value); + break; + case kUpb_CType_UInt64: + ret.uint64_val = NUM2ULL(value); + break; + default: + rb_raise(cTypeError, "Convert_RubyToUpb(): Unexpected type %d", + (int)type_info.type); + } + break; + default: + rb_raise(cTypeError, + "Convert_RubyToUpb(): Unexpected type %d", (int)type_info.type); + } + + return ret; +} + +VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info, + VALUE arena) { + switch (type_info.type) { + case kUpb_CType_Float: + return DBL2NUM(upb_val.float_val); + case kUpb_CType_Double: + return DBL2NUM(upb_val.double_val); + case kUpb_CType_Bool: + return upb_val.bool_val ? Qtrue : Qfalse; + case kUpb_CType_Int32: + return INT2NUM(upb_val.int32_val); + case kUpb_CType_Int64: + return LL2NUM(upb_val.int64_val); + case kUpb_CType_UInt32: + return UINT2NUM(upb_val.uint32_val); + case kUpb_CType_UInt64: + return ULL2NUM(upb_val.int64_val); + case kUpb_CType_Enum: { + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber( + type_info.def.enumdef, upb_val.int32_val); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + } else { + return INT2NUM(upb_val.int32_val); + } + } + case kUpb_CType_String: { + VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); + rb_enc_associate(str_rb, rb_utf8_encoding()); + rb_obj_freeze(str_rb); + return str_rb; + } + case kUpb_CType_Bytes: { + VALUE str_rb = rb_str_new(upb_val.str_val.data, upb_val.str_val.size); + rb_enc_associate(str_rb, rb_ascii8bit_encoding()); + rb_obj_freeze(str_rb); + return str_rb; + } + case kUpb_CType_Message: + return Message_GetRubyWrapper((upb_Message*)upb_val.msg_val, + type_info.def.msgdef, arena); + default: + rb_raise(rb_eRuntimeError, "Convert_UpbToRuby(): Unexpected type %d", + (int)type_info.type); + } +} + +upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, + upb_Arena* arena) { + upb_MessageValue new_msgval; + + switch (type_info.type) { + default: + memcpy(&new_msgval, &msgval, sizeof(msgval)); + break; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + size_t n = msgval.str_val.size; + char* mem = upb_Arena_Malloc(arena, n); + new_msgval.str_val.data = mem; + new_msgval.str_val.size = n; + memcpy(mem, msgval.str_val.data, n); + break; + } + case kUpb_CType_Message: + new_msgval.msg_val = + Message_deep_copy(msgval.msg_val, type_info.def.msgdef, arena); + break; + } + + return new_msgval; +} + +bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + TypeInfo type_info) { + upb_Status status; + upb_Status_Clear(&status); + bool return_value = shared_Msgval_IsEqual(val1, val2, type_info.type, + type_info.def.msgdef, &status); + if (upb_Status_IsOk(&status)) { + return return_value; + } else { + rb_raise(rb_eRuntimeError, "Msgval_IsEqual(): %s", + upb_Status_ErrorMessage(&status)); + } +} + +uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info, + uint64_t seed) { + upb_Status status; + upb_Status_Clear(&status); + uint64_t return_value = shared_Msgval_GetHash( + val, type_info.type, type_info.def.msgdef, seed, &status); + if (upb_Status_IsOk(&status)) { + return return_value; + } else { + rb_raise(rb_eRuntimeError, "Msgval_GetHash(): %s", + upb_Status_ErrorMessage(&status)); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h new file mode 100755 index 0000000..ac3eaab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/convert.h @@ -0,0 +1,50 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_CONVERT_H_ +#define RUBY_PROTOBUF_CONVERT_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Converts |ruby_val| to a upb_MessageValue according to |type_info|. +// +// The |arena| parameter indicates the lifetime of the container where this +// value will be assigned. It is used as follows: +// - If type is string or bytes, the string data will be copied into |arena|. +// - If type is message, and we need to auto-construct a message due to implicit +// conversions (eg. Time -> Google::Protobuf::Timestamp), the new message +// will be created in |arena|. +// - If type is message and the Ruby value is a message instance, we will fuse +// the message's arena into |arena|, to ensure that this message outlives the +// container. +upb_MessageValue Convert_RubyToUpb(VALUE ruby_val, const char *name, + TypeInfo type_info, upb_Arena *arena); + +// Converts |upb_val| to a Ruby VALUE according to |type_info|. This may involve +// creating a Ruby wrapper object. +// +// The |arena| parameter indicates the arena that owns the lifetime of +// |upb_val|. Any Ruby wrapper object that is created will reference |arena| +// and ensure it outlives the wrapper. +VALUE Convert_UpbToRuby(upb_MessageValue upb_val, TypeInfo type_info, + VALUE arena); + +// Creates a deep copy of |msgval| in |arena|. +upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, + upb_Arena *arena); + +// Returns true if |val1| and |val2| are equal. Their type is given by +// |type_info|. +bool Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + TypeInfo type_info); + +// Returns a hash value for the given upb_MessageValue. +uint64_t Msgval_GetHash(upb_MessageValue val, TypeInfo type_info, + uint64_t seed); + +#endif // RUBY_PROTOBUF_CONVERT_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c new file mode 100755 index 0000000..5bc405f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.c @@ -0,0 +1,2084 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include <ctype.h> +#include <errno.h> + +#include "convert.h" +#include "message.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor +// instances. +// ----------------------------------------------------------------------------- + +static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def); +static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def); +static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def); +static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def); +static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def); +static VALUE get_servicedef_obj(VALUE descriptor_pool, + const upb_ServiceDef* def); +static VALUE get_methoddef_obj(VALUE descriptor_pool, const upb_MethodDef* def); + +// A distinct object that is not accessible from Ruby. We use this as a +// constructor argument to enforce that certain objects cannot be created from +// Ruby. +VALUE c_only_cookie = Qnil; + +// ----------------------------------------------------------------------------- +// Common utilities. +// ----------------------------------------------------------------------------- + +static const char* get_str(VALUE str) { + Check_Type(str, T_STRING); + return RSTRING_PTR(str); +} + +static VALUE rb_str_maybe_null(const char* s) { + if (s == NULL) { + s = ""; + } + return rb_str_new2(s); +} +static ID options_instancevar_interned; +// ----------------------------------------------------------------------------- +// DescriptorPool. +// ----------------------------------------------------------------------------- + +typedef struct { + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE def_to_descriptor; // Hash table of def* -> Ruby descriptor. + upb_DefPool* symtab; +} DescriptorPool; + +VALUE cDescriptorPool = Qnil; + +// Global singleton DescriptorPool. The user is free to create others, but this +// is used by generated code. +VALUE generated_pool = Qnil; + +static void DescriptorPool_mark(void* _self) { + DescriptorPool* self = _self; + rb_gc_mark(self->def_to_descriptor); +} + +static void DescriptorPool_free(void* _self) { + DescriptorPool* self = _self; + upb_DefPool_Free(self->symtab); + xfree(self); +} + +static const rb_data_type_t DescriptorPool_type = { + "Google::Protobuf::DescriptorPool", + {DescriptorPool_mark, DescriptorPool_free, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static DescriptorPool* ruby_to_DescriptorPool(VALUE val) { + DescriptorPool* ret; + TypedData_Get_Struct(val, DescriptorPool, &DescriptorPool_type, ret); + return ret; +} + +// Exposed to other modules in defs.h. +const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb) { + DescriptorPool* pool = ruby_to_DescriptorPool(desc_pool_rb); + return pool->symtab; +} + +/** + * ruby-doc: DescriptorPool + * + * A DescriptorPool is the registry of all known Protobuf descriptor objects. + * + */ + +/* + * ruby-doc: DescriptorPool.new + * + * Creates a new, empty, descriptor pool. + */ +static VALUE DescriptorPool_alloc(VALUE klass) { + DescriptorPool* self = ALLOC(DescriptorPool); + VALUE ret; + + self->def_to_descriptor = Qnil; + ret = TypedData_Wrap_Struct(klass, &DescriptorPool_type, self); + + RB_OBJ_WRITE(ret, &self->def_to_descriptor, rb_hash_new()); + self->symtab = upb_DefPool_New(); + + // Ruby treats all enums as open. + upb_DefPool_DisableClosedEnumChecking(self->symtab); + + return ObjectCache_TryAdd(self->symtab, ret); +} + +/* + * ruby-doc: DescriptorPool#add_serialized_file + * + * Adds the given serialized + * {https://protobuf.com/docs/descriptors#file-descriptors FileDescriptorProto} + * to the pool. + * + * @param serialized_file_proto [String] + * @return [FileDescriptor] + */ +VALUE DescriptorPool_add_serialized_file(VALUE _self, + VALUE serialized_file_proto) { + DescriptorPool* self = ruby_to_DescriptorPool(_self); + Check_Type(serialized_file_proto, T_STRING); + VALUE arena_rb = Arena_new(); + upb_Arena* arena = Arena_get(arena_rb); + google_protobuf_FileDescriptorProto* file_proto = + google_protobuf_FileDescriptorProto_parse( + RSTRING_PTR(serialized_file_proto), + RSTRING_LEN(serialized_file_proto), arena); + if (!file_proto) { + rb_raise(rb_eArgError, "Unable to parse FileDescriptorProto"); + } + upb_Status status; + upb_Status_Clear(&status); + const upb_FileDef* filedef = + upb_DefPool_AddFile(self->symtab, file_proto, &status); + if (!filedef) { + rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s", + upb_Status_ErrorMessage(&status)); + } + RB_GC_GUARD(arena_rb); + return get_filedef_obj(_self, filedef); +} + +/* + * ruby-doc: DescriptorPool#lookup + * + * Finds a {Descriptor}, {EnumDescriptor}, + * {FieldDescriptor} or {ServiceDescriptor} by + * name and returns it, or nil if none exists with the given name. + * + * @param name [String] + * @return [Descriptor,EnumDescriptor,FieldDescriptor,ServiceDescriptor] + */ +static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) { + DescriptorPool* self = ruby_to_DescriptorPool(_self); + const char* name_str = get_str(name); + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; + const upb_FieldDef* fielddef; + const upb_ServiceDef* servicedef; + const upb_FileDef* filedef; + + msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str); + if (msgdef) { + return get_msgdef_obj(_self, msgdef); + } + + fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str); + if (fielddef) { + return get_fielddef_obj(_self, fielddef); + } + + enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str); + if (enumdef) { + return get_enumdef_obj(_self, enumdef); + } + + servicedef = upb_DefPool_FindServiceByName(self->symtab, name_str); + if (servicedef) { + return get_servicedef_obj(_self, servicedef); + } + + filedef = upb_DefPool_FindFileByName(self->symtab, name_str); + if (filedef) { + return get_filedef_obj(_self, filedef); + } + + return Qnil; +} + +/* + * ruby-doc: DescriptorPool.generated_pool + * + * Class method that returns the global {DescriptorPool}. This is a singleton + * into which generated-code message and enum types are registered. The user may + * also register types in this pool for convenience so that they do not have to + * hold a reference to a private pool instance. + * + * @return [DescriptorPool] + */ +static VALUE DescriptorPool_generated_pool(VALUE _self) { + return generated_pool; +} + +static void DescriptorPool_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "DescriptorPool", rb_cObject); + rb_define_alloc_func(klass, DescriptorPool_alloc); + rb_define_method(klass, "add_serialized_file", + DescriptorPool_add_serialized_file, 1); + rb_define_method(klass, "lookup", DescriptorPool_lookup, 1); + rb_define_singleton_method(klass, "generated_pool", + DescriptorPool_generated_pool, 0); + rb_gc_register_address(&cDescriptorPool); + cDescriptorPool = klass; + + rb_gc_register_address(&generated_pool); + generated_pool = rb_class_new_instance(0, NULL, klass); + options_instancevar_interned = rb_intern("options"); +} + +// ----------------------------------------------------------------------------- +// Descriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_MessageDef* msgdef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE klass; + VALUE descriptor_pool; +} Descriptor; + +VALUE cDescriptor = Qnil; + +static void Descriptor_mark(void* _self) { + Descriptor* self = _self; + rb_gc_mark(self->klass); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t Descriptor_type = { + "Google::Protobuf::Descriptor", + {Descriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static Descriptor* ruby_to_Descriptor(VALUE val) { + Descriptor* ret; + TypedData_Get_Struct(val, Descriptor, &Descriptor_type, ret); + return ret; +} + +// Decode and return a frozen instance of a Descriptor Option for the given pool +static VALUE decode_options(VALUE self, const char* option_type, int size, + const char* bytes, VALUE descriptor_pool) { + VALUE options_rb = rb_ivar_get(self, options_instancevar_interned); + if (options_rb != Qnil) { + return options_rb; + } + + static const char* prefix = "google.protobuf."; + char fullname + [/*strlen(prefix)*/ 16 + + /*strln(longest option type supported e.g. "MessageOptions")*/ 14 + + /*null terminator*/ 1]; + + snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type); + const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName( + ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname); + if (!msgdef) { + rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type); + } + + VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef); + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + + options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, false); + + // Strip features from the options proto to keep it internal. + const upb_MessageDef* decoded_desc = NULL; + upb_Message* options = Message_GetMutable(options_rb, &decoded_desc); + PBRUBY_ASSERT(options != NULL); + PBRUBY_ASSERT(decoded_desc == msgdef); + const upb_FieldDef* field = + upb_MessageDef_FindFieldByName(decoded_desc, "features"); + PBRUBY_ASSERT(field != NULL); + upb_Message_ClearFieldByDef(options, field); + + Message_freeze(options_rb); + + rb_ivar_set(self, options_instancevar_interned, options_rb); + return options_rb; +} + +/* + * ruby-doc: Descriptor + * + * A Descriptor provides information about a given Protobuf definition. + */ + +/* + * ruby-doc: Descriptor.initialize + * + * Creates a new, empty, message type descriptor. At a minimum, its name must be + * set before it is added to a pool. It cannot be used to create messages until + * it is added to a pool, after which it becomes immutable (as part of a + * finalization process). + */ +static VALUE Descriptor_alloc(VALUE klass) { + Descriptor* self = ALLOC(Descriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &Descriptor_type, self); + self->msgdef = NULL; + self->klass = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +/* + * call-seq: + * Descriptor.new(c_only_cookie, ptr) => Descriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE Descriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + Descriptor* self = ruby_to_Descriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->msgdef = (const upb_MessageDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: Descriptor#file_descriptor + * + * Returns the {FileDescriptor} object this message belongs to. + * + * @return [FileDescriptor] + */ +static VALUE Descriptor_file_descriptor(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + return get_filedef_obj(self->descriptor_pool, + upb_MessageDef_File(self->msgdef)); +} + +/* + * ruby-doc: Descriptor#name + * + * Returns the name of this message type as a fully-qualified string (e.g., + * My.Package.MessageType). + * + * @return [String] + */ +static VALUE Descriptor_name(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + return rb_str_maybe_null(upb_MessageDef_FullName(self->msgdef)); +} + +/* + * ruby-doc: Descriptor#each + * + * Iterates over fields in this message type, yielding to the block on each one. + * + * @yield [FieldDescriptor] + * @return [nil] + */ +static VALUE Descriptor_each(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + + int n = upb_MessageDef_FieldCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* field = upb_MessageDef_Field(self->msgdef, i); + VALUE obj = get_fielddef_obj(self->descriptor_pool, field); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: Descriptor#lookup + * + * Returns the field descriptor for the field with the given name, if present, + * or nil if none. + * + * @param name [String] + * @return [FieldDescriptor] + */ +static VALUE Descriptor_lookup(VALUE _self, VALUE name) { + Descriptor* self = ruby_to_Descriptor(_self); + const char* s = get_str(name); + const upb_FieldDef* field = upb_MessageDef_FindFieldByName(self->msgdef, s); + if (field == NULL) { + return Qnil; + } + return get_fielddef_obj(self->descriptor_pool, field); +} + +/* + * ruby-doc: Descriptor#each_oneof + * + * Invokes the given block for each oneof in this message type, passing the + * corresponding {OneofDescriptor}. + * + * @yield [OneofDescriptor] + * @return [nil] + */ +static VALUE Descriptor_each_oneof(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + + int n = upb_MessageDef_OneofCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_OneofDef* oneof = upb_MessageDef_Oneof(self->msgdef, i); + VALUE obj = get_oneofdef_obj(self->descriptor_pool, oneof); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: Descriptor#lookup_oneof + * + * Returns the oneof descriptor for the oneof with the given name, if present, + * or nil if none. + * + * @param name [String] + * @return [OneofDescriptor] + */ +static VALUE Descriptor_lookup_oneof(VALUE _self, VALUE name) { + Descriptor* self = ruby_to_Descriptor(_self); + const char* s = get_str(name); + const upb_OneofDef* oneof = upb_MessageDef_FindOneofByName(self->msgdef, s); + if (oneof == NULL) { + return Qnil; + } + return get_oneofdef_obj(self->descriptor_pool, oneof); +} + +/* + * ruby-doc: Descriptor#msgclass + * + * Returns the Ruby class created for this message type. + * + * @return [Class<Google::Protobuf::AbstractMessage>] + */ +static VALUE Descriptor_msgclass(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + if (self->klass == Qnil) { + RB_OBJ_WRITE(_self, &self->klass, build_class_from_descriptor(_self)); + } + return self->klass; +} + +/* + * ruby-doc: Descriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L571 + * MessageOptions} for this {Descriptor}. + * + * @return [MessageOptions] + */ +static VALUE Descriptor_options(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + const google_protobuf_MessageOptions* opts = + upb_MessageDef_Options(self->msgdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_MessageOptions_serialize(opts, arena, &size); + VALUE message_options = decode_options(_self, "MessageOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return message_options; +} + +/* + * ruby-doc: Descriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L147 + * DescriptorProto} of this {Descriptor}. + * + * @return [DescriptorProto] + */ +static VALUE Descriptor_to_proto(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_DescriptorProto* proto = + upb_MessageDef_ToProto(self->msgdef, arena); + size_t size; + const char* serialized = + google_protobuf_DescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::DescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void Descriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject); + rb_define_alloc_func(klass, Descriptor_alloc); + rb_define_method(klass, "initialize", Descriptor_initialize, 3); + rb_define_method(klass, "each", Descriptor_each, 0); + rb_define_method(klass, "lookup", Descriptor_lookup, 1); + rb_define_method(klass, "each_oneof", Descriptor_each_oneof, 0); + rb_define_method(klass, "lookup_oneof", Descriptor_lookup_oneof, 1); + rb_define_method(klass, "msgclass", Descriptor_msgclass, 0); + rb_define_method(klass, "name", Descriptor_name, 0); + rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0); + rb_define_method(klass, "options", Descriptor_options, 0); + rb_define_method(klass, "to_proto", Descriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cDescriptor); + cDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// FileDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_FileDef* filedef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE descriptor_pool; // Owns the upb_FileDef. +} FileDescriptor; + +static VALUE cFileDescriptor = Qnil; + +static void FileDescriptor_mark(void* _self) { + FileDescriptor* self = _self; + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t FileDescriptor_type = { + "Google::Protobuf::FileDescriptor", + {FileDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static FileDescriptor* ruby_to_FileDescriptor(VALUE val) { + FileDescriptor* ret; + TypedData_Get_Struct(val, FileDescriptor, &FileDescriptor_type, ret); + return ret; +} + +static VALUE FileDescriptor_alloc(VALUE klass) { + FileDescriptor* self = ALLOC(FileDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &FileDescriptor_type, self); + self->descriptor_pool = Qnil; + self->filedef = NULL; + return ret; +} + +/** + * ruby-doc: FileDescriptor + * + * A FileDescriptor provides information about all Protobuf definitions in a + * particular file. + */ + +/* + * ruby-doc: FileDescriptor#initialize + * + * Returns a new file descriptor. May + * to a builder. + */ +static VALUE FileDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->filedef = (const upb_FileDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: FileDescriptor#name + * + * Returns the name of the file. + * + * @return [String] + */ +static VALUE FileDescriptor_name(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + const char* name = upb_FileDef_Name(self->filedef); + return name == NULL ? Qnil : rb_str_new2(name); +} + +/* + * ruby-doc: FileDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L442 + * FileOptions} for this {FileDescriptor}. + * + * @return [FileOptions] + */ +static VALUE FileDescriptor_options(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size); + VALUE file_options = decode_options(_self, "FileOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return file_options; +} + +/* + * ruby-doc: FileDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L104 + * FileDescriptorProto} of this {FileDescriptor}. + * + * @return [FileDescriptorProto] + */ +static VALUE FileDescriptor_to_proto(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_FileDescriptorProto* file_proto = + upb_FileDef_ToProto(self->filedef, arena); + + size_t size; + const char* serialized = + google_protobuf_FileDescriptorProto_serialize(file_proto, arena, &size); + + VALUE file_proto_class = + rb_path2class("Google::Protobuf::FileDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, file_proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void FileDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject); + rb_define_alloc_func(klass, FileDescriptor_alloc); + rb_define_method(klass, "initialize", FileDescriptor_initialize, 3); + rb_define_method(klass, "name", FileDescriptor_name, 0); + rb_define_method(klass, "options", FileDescriptor_options, 0); + rb_define_method(klass, "to_proto", FileDescriptor_to_proto, 0); + rb_gc_register_address(&cFileDescriptor); + cFileDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// FieldDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_FieldDef* fielddef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE descriptor_pool; // Owns the upb_FieldDef. +} FieldDescriptor; + +static VALUE cFieldDescriptor = Qnil; + +static void FieldDescriptor_mark(void* _self) { + FieldDescriptor* self = _self; + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t FieldDescriptor_type = { + "Google::Protobuf::FieldDescriptor", + {FieldDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static FieldDescriptor* ruby_to_FieldDescriptor(VALUE val) { + FieldDescriptor* ret; + TypedData_Get_Struct(val, FieldDescriptor, &FieldDescriptor_type, ret); + return ret; +} + +/** + * ruby-doc: FieldDescriptor + * + * A FieldDescriptor provides information about the Protobuf definition of a + * field inside a {Descriptor}. + */ + +/* + * ruby-doc: FieldDescriptor#initialize + * + * Returns a new field descriptor. Its name, type, etc. must be set before it is + * added to a message type. + */ +static VALUE FieldDescriptor_alloc(VALUE klass) { + FieldDescriptor* self = ALLOC(FieldDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &FieldDescriptor_type, self); + self->fielddef = NULL; + return ret; +} + +/* + * call-seq: + * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE FieldDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->fielddef = (const upb_FieldDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#name + * + * Returns the name of this field. + * + * @return [String] + */ +static VALUE FieldDescriptor_name(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return rb_str_maybe_null(upb_FieldDef_Name(self->fielddef)); +} + +// Non-static, exposed to other .c files. +upb_CType ruby_to_fieldtype(VALUE type) { + if (TYPE(type) != T_SYMBOL) { + rb_raise(rb_eArgError, "Expected symbol for field type."); + } + +#define CONVERT(upb, ruby) \ + if (SYM2ID(type) == rb_intern(#ruby)) { \ + return kUpb_CType_##upb; \ + } + + CONVERT(Float, float); + CONVERT(Double, double); + CONVERT(Bool, bool); + CONVERT(String, string); + CONVERT(Bytes, bytes); + CONVERT(Message, message); + CONVERT(Enum, enum); + CONVERT(Int32, int32); + CONVERT(Int64, int64); + CONVERT(UInt32, uint32); + CONVERT(UInt64, uint64); + +#undef CONVERT + + rb_raise(rb_eArgError, "Unknown field type."); + return 0; +} + +static VALUE descriptortype_to_ruby(upb_FieldType type) { + switch (type) { +#define CONVERT(upb, ruby) \ + case kUpb_FieldType_##upb: \ + return ID2SYM(rb_intern(#ruby)); + CONVERT(Float, float); + CONVERT(Double, double); + CONVERT(Bool, bool); + CONVERT(String, string); + CONVERT(Bytes, bytes); + CONVERT(Message, message); + CONVERT(Group, group); + CONVERT(Enum, enum); + CONVERT(Int32, int32); + CONVERT(Int64, int64); + CONVERT(UInt32, uint32); + CONVERT(UInt64, uint64); + CONVERT(SInt32, sint32); + CONVERT(SInt64, sint64); + CONVERT(Fixed32, fixed32); + CONVERT(Fixed64, fixed64); + CONVERT(SFixed32, sfixed32); + CONVERT(SFixed64, sfixed64); +#undef CONVERT + } + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#type + * + * Returns this field's type, as a Ruby symbol, or nil if not yet set. + * + * Valid field types are: + * :int32, :int64, :uint32, :uint64, :float, :double, :bool, :string, + * :bytes, :message. + * + * @return [Symbol] + */ +static VALUE FieldDescriptor__type(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return descriptortype_to_ruby(upb_FieldDef_Type(self->fielddef)); +} + +/* + * ruby-doc: FieldDescriptor#default + * + * Returns this field's default, as a Ruby object, or nil if not yet set. + * + * @return [Object,nil] + */ +static VALUE FieldDescriptor_default(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_FieldDef* f = self->fielddef; + upb_MessageValue default_val = upb_MessageValue_Zero(); + if (upb_FieldDef_IsSubMessage(f)) { + return Qnil; + } else if (!upb_FieldDef_IsRepeated(f)) { + default_val = upb_FieldDef_Default(f); + } + return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil); +} + +/* + * ruby-doc: FieldDescriptor.has_presence? + * + * Returns whether this field tracks presence. + * + * @return [Boolean] + */ +static VALUE FieldDescriptor_has_presence(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_HasPresence(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#required? + * + * Returns whether this is a required field. + * + * @return [Boolean] + */ +static VALUE FieldDescriptor_is_required(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_IsRequired(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#repeated? + * + * Returns whether this is a repeated field. + * @return [Boolean] + */ +static VALUE FieldDescriptor_is_repeated(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_IsRepeated(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#is_packed? + * + * Returns whether this is a repeated field that uses packed encoding. + * @return [Boolean] + */ +static VALUE FieldDescriptor_is_packed(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return upb_FieldDef_IsPacked(self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#json_name + * + * Returns this field's json_name, as a Ruby string, or nil if not yet set. + * + * @return [String,nil] + */ +static VALUE FieldDescriptor_json_name(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_FieldDef* f = self->fielddef; + const char* json_name = upb_FieldDef_JsonName(f); + return rb_str_new2(json_name); +} + +/* + * ruby-doc: FieldDescriptor#label + * + * Returns this field's label (i.e., plurality), as a Ruby symbol. + * Valid field labels are: + * :optional, :repeated + * + * @return [Symbol] + * @deprecated Use {#repeated?} or {#required?} instead. + */ +static VALUE FieldDescriptor_label(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + switch (upb_FieldDef_Label(self->fielddef)) { +#define CONVERT(upb, ruby) \ + case kUpb_Label_##upb: \ + return ID2SYM(rb_intern(#ruby)); + + CONVERT(Optional, optional); + CONVERT(Required, required); + CONVERT(Repeated, repeated); + +#undef CONVERT + } + + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#number + * + * Returns the tag number for this field. + * + * @return [Integer] + */ +static VALUE FieldDescriptor_number(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + return INT2NUM(upb_FieldDef_Number(self->fielddef)); +} + +/* + * ruby-doc: FieldDescriptor#submsg_name + * + * Returns the name of the message or enum type corresponding to this field, if + * it is a message or enum field (respectively), or nil otherwise. This type + * name will be resolved within the context of the pool to which the containing + * message type is added. + * + * @return [String,nil] + */ +static VALUE FieldDescriptor_submsg_name(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + switch (upb_FieldDef_CType(self->fielddef)) { + case kUpb_CType_Enum: + return rb_str_new2( + upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(self->fielddef))); + case kUpb_CType_Message: + return rb_str_new2( + upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(self->fielddef))); + default: + return Qnil; + } +} + +/* + * ruby-doc: FieldDescriptor#subtype + * + * Returns the message or enum descriptor corresponding to this field's type if + * it is a message or enum field, respectively, or nil otherwise. Cannot be + * called *until* the containing message type is added to a pool (and thus + * resolved). + * + * @return [Descriptor,EnumDescriptor,nil] + */ +static VALUE FieldDescriptor_subtype(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + switch (upb_FieldDef_CType(self->fielddef)) { + case kUpb_CType_Enum: + return get_enumdef_obj(self->descriptor_pool, + upb_FieldDef_EnumSubDef(self->fielddef)); + case kUpb_CType_Message: + return get_msgdef_obj(self->descriptor_pool, + upb_FieldDef_MessageSubDef(self->fielddef)); + default: + return Qnil; + } +} + +/* + * ruby-doc: FieldDescriptor#get + * + * Returns the value set for this field on the given message. Raises an + * exception if message is of the wrong type. + * + * @param message [AbstractMessage] + * @return [Object] + */ +static VALUE FieldDescriptor_get(VALUE _self, VALUE msg_rb) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + + Message_Get(msg_rb, &m); + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "get method called on wrong message type"); + } + + return Message_getfield(msg_rb, self->fielddef); +} + +/* + * ruby-doc: FieldDescriptor.has? + * + * Returns whether the value is set on the given message. Raises an + * exception when calling for fields that do not have presence. + * + * @param message [AbstractMessage] + * @return [Boolean] + */ +static VALUE FieldDescriptor_has(VALUE _self, VALUE msg_rb) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + const upb_Message* msg = Message_Get(msg_rb, &m); + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "has method called on wrong message type"); + } else if (!upb_FieldDef_HasPresence(self->fielddef)) { + rb_raise(rb_eArgError, "does not track presence"); + } + + return upb_Message_HasFieldByDef(msg, self->fielddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: FieldDescriptor#clear + * + * Clears the field from the message if it's set. + * + * @param message [AbstractMessage] + * @return [nil] + */ +static VALUE FieldDescriptor_clear(VALUE _self, VALUE msg_rb) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + upb_Message* msg = Message_GetMutable(msg_rb, &m); + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "has method called on wrong message type"); + } + + upb_Message_ClearFieldByDef(msg, self->fielddef); + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#set + * + * Sets the value corresponding to this field to the given value on the given + * message. Raises an exception if message is of the wrong type. Performs the + * ordinary type-checks for field setting. + * + * @param message [AbstractMessage] + * @param value [Object] + */ +static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const upb_MessageDef* m; + upb_Message* msg = Message_GetMutable(msg_rb, &m); + upb_Arena* arena = Arena_get(Message_GetArena(msg_rb)); + upb_MessageValue msgval; + + if (m != upb_FieldDef_ContainingType(self->fielddef)) { + rb_raise(cTypeError, "set method called on wrong message type"); + } + + msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef), + TypeInfo_get(self->fielddef), arena); + upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena); + return Qnil; +} + +/* + * ruby-doc: FieldDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L656 + * FieldOptions} for this {FieldDescriptor}. + * + * @return [FieldOptions] + */ +static VALUE FieldDescriptor_options(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const google_protobuf_FieldOptions* opts = + upb_FieldDef_Options(self->fielddef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size); + VALUE field_options = decode_options(_self, "FieldOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return field_options; +} + +/* + * ruby-doc: FieldDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L236 + * FieldDescriptorProto} of this {FieldDescriptor}. + * + * @return [FieldDescriptorProto] + */ +static VALUE FieldDescriptor_to_proto(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_FieldDescriptorProto* proto = + upb_FieldDef_ToProto(self->fielddef, arena); + size_t size; + const char* serialized = + google_protobuf_FieldDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::FieldDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void FieldDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject); + rb_define_alloc_func(klass, FieldDescriptor_alloc); + rb_define_method(klass, "initialize", FieldDescriptor_initialize, 3); + rb_define_method(klass, "name", FieldDescriptor_name, 0); + rb_define_method(klass, "type", FieldDescriptor__type, 0); + rb_define_method(klass, "default", FieldDescriptor_default, 0); + rb_define_method(klass, "has_presence?", FieldDescriptor_has_presence, 0); + rb_define_method(klass, "required?", FieldDescriptor_is_required, 0); + rb_define_method(klass, "repeated?", FieldDescriptor_is_repeated, 0); + rb_define_method(klass, "is_packed?", FieldDescriptor_is_packed, 0); + rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0); + rb_define_method(klass, "label", FieldDescriptor_label, 0); + rb_define_method(klass, "number", FieldDescriptor_number, 0); + rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0); + rb_define_method(klass, "subtype", FieldDescriptor_subtype, 0); + rb_define_method(klass, "has?", FieldDescriptor_has, 1); + rb_define_method(klass, "clear", FieldDescriptor_clear, 1); + rb_define_method(klass, "get", FieldDescriptor_get, 1); + rb_define_method(klass, "set", FieldDescriptor_set, 2); + rb_define_method(klass, "options", FieldDescriptor_options, 0); + rb_define_method(klass, "to_proto", FieldDescriptor_to_proto, 0); + rb_gc_register_address(&cFieldDescriptor); + cFieldDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// OneofDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_OneofDef* oneofdef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE descriptor_pool; // Owns the upb_OneofDef. +} OneofDescriptor; + +static VALUE cOneofDescriptor = Qnil; + +static void OneofDescriptor_mark(void* _self) { + OneofDescriptor* self = _self; + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t OneofDescriptor_type = { + "Google::Protobuf::OneofDescriptor", + {OneofDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static OneofDescriptor* ruby_to_OneofDescriptor(VALUE val) { + OneofDescriptor* ret; + TypedData_Get_Struct(val, OneofDescriptor, &OneofDescriptor_type, ret); + return ret; +} + +/** + * ruby-doc: OneofDescriptor + * + * A OneofDescriptor provides information about the Protobuf definition of a + * oneof inside a {Descriptor}. + */ + +/* + * ruby-doc: OneofDescriptor#initialize + * + * Creates a new, empty, oneof descriptor. The oneof may only be modified prior + * to being added to a message descriptor which is subsequently added to a pool. + */ +static VALUE OneofDescriptor_alloc(VALUE klass) { + OneofDescriptor* self = ALLOC(OneofDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &OneofDescriptor_type, self); + self->oneofdef = NULL; + self->descriptor_pool = Qnil; + return ret; +} + +/* + * call-seq: + * OneofDescriptor.new(c_only_cookie, pool, ptr) => OneofDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE OneofDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->oneofdef = (const upb_OneofDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: OneofDescriptor#name + * + * Returns the name of this oneof. + * + * @return [String] + */ +static VALUE OneofDescriptor_name(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + return rb_str_maybe_null(upb_OneofDef_Name(self->oneofdef)); +} + +/* + * ruby-doc: OneofDescriptor#each + * + * Iterates through fields in this oneof, yielding to the block on each one. + * + * @yield [FieldDescriptor] + * @return [nil] + */ +static VALUE OneofDescriptor_each(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + + int n = upb_OneofDef_FieldCount(self->oneofdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* f = upb_OneofDef_Field(self->oneofdef, i); + VALUE obj = get_fielddef_obj(self->descriptor_pool, f); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: OneofDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L824 + * OneofOptions} for this {OneofDescriptor}. + * + * @return [OneofOptions] + */ +static VALUE OneOfDescriptor_options(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + const google_protobuf_OneofOptions* opts = + upb_OneofDef_Options(self->oneofdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size); + VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return oneof_options; +} + +/* + * ruby-doc: OneofDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L343 + * OneofDescriptorProto} of this {OneofDescriptor}. + * + * @return [OneofDescriptorProto] + */ +static VALUE OneOfDescriptor_to_proto(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_OneofDescriptorProto* proto = + upb_OneofDef_ToProto(self->oneofdef, arena); + size_t size; + const char* serialized = + google_protobuf_OneofDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::OneofDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void OneofDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject); + rb_define_alloc_func(klass, OneofDescriptor_alloc); + rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3); + rb_define_method(klass, "name", OneofDescriptor_name, 0); + rb_define_method(klass, "each", OneofDescriptor_each, 0); + rb_define_method(klass, "options", OneOfDescriptor_options, 0); + rb_define_method(klass, "to_proto", OneOfDescriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cOneofDescriptor); + cOneofDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// EnumDescriptor. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_EnumDef* enumdef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_EnumDef. +} EnumDescriptor; + +static VALUE cEnumDescriptor = Qnil; + +static void EnumDescriptor_mark(void* _self) { + EnumDescriptor* self = _self; + rb_gc_mark(self->module); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t EnumDescriptor_type = { + "Google::Protobuf::EnumDescriptor", + {EnumDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static EnumDescriptor* ruby_to_EnumDescriptor(VALUE val) { + EnumDescriptor* ret; + TypedData_Get_Struct(val, EnumDescriptor, &EnumDescriptor_type, ret); + return ret; +} + +static VALUE EnumDescriptor_alloc(VALUE klass) { + EnumDescriptor* self = ALLOC(EnumDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &EnumDescriptor_type, self); + self->enumdef = NULL; + self->module = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +// Exposed to other modules in defs.h. +const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb) { + EnumDescriptor* desc = ruby_to_EnumDescriptor(enum_desc_rb); + return desc->enumdef; +} + +/** + * ruby-doc: EnumDescriptor + * + * An EnumDescriptor provides information about the Protobuf definition of an + * enum inside a {Descriptor}. + */ + +/* + * call-seq: + * EnumDescriptor.new(c_only_cookie, ptr) => EnumDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE EnumDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->enumdef = (const upb_EnumDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: EnumDescriptor#file_descriptor + * + * Returns the {FileDescriptor} object this enum belongs to. + * + * @return [FileDescriptor] + */ +static VALUE EnumDescriptor_file_descriptor(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + return get_filedef_obj(self->descriptor_pool, + upb_EnumDef_File(self->enumdef)); +} + +/* + * ruby-doc: EnumDescriptor#is_closed? + * + * Returns whether this enum is open or closed. + * + * @return [Boolean] + */ +static VALUE EnumDescriptor_is_closed(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + return upb_EnumDef_IsClosed(self->enumdef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: EnumDescriptor#name + * + * Returns the name of this enum type. + * + * @return [String] + */ +static VALUE EnumDescriptor_name(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + return rb_str_maybe_null(upb_EnumDef_FullName(self->enumdef)); +} + +/* + * ruby-doc: EnumDescriptor#lookup_name + * + * Returns the numeric value corresponding to the given key name (as a Ruby + * symbol), or nil if none. + * + * @param name [Symbol] + * @return [Integer,nil] + */ +static VALUE EnumDescriptor_lookup_name(VALUE _self, VALUE name) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + const char* name_str = rb_id2name(SYM2ID(name)); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByName(self->enumdef, name_str); + if (ev) { + return INT2NUM(upb_EnumValueDef_Number(ev)); + } else { + return Qnil; + } +} + +/* + * ruby-doc: EnumDescriptor#lookup_value + * + * Returns the key name (as a Ruby symbol) corresponding to the integer value, + * or nil if none. + * + * @param name [Integer] + * @return [Symbol,nil] + */ +static VALUE EnumDescriptor_lookup_value(VALUE _self, VALUE number) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + int32_t val = NUM2INT(number); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(self->enumdef, val); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + } else { + return Qnil; + } +} + +/* + * ruby-doc: EnumDescriptor#each + * + * Iterates over key => value mappings in this enum's definition, yielding to + * the block with (key, value) arguments for each one. + * + * @yield [Symbol, Integer] + * @return [nil] + */ +static VALUE EnumDescriptor_each(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + + int n = upb_EnumDef_ValueCount(self->enumdef); + for (int i = 0; i < n; i++) { + const upb_EnumValueDef* ev = upb_EnumDef_Value(self->enumdef, i); + VALUE key = ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + VALUE number = INT2NUM(upb_EnumValueDef_Number(ev)); + rb_yield_values(2, key, number); + } + + return Qnil; +} + +/* + * ruby-doc: EnumDescriptor#enummodule + * + * Returns the Ruby module corresponding to this enum type. + * + * @return [Module] + */ +static VALUE EnumDescriptor_enummodule(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + if (self->module == Qnil) { + RB_OBJ_WRITE(_self, &self->module, build_module_from_enumdesc(_self)); + } + return self->module; +} + +/* + * ruby-doc: EnumDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L838 + * EnumOptions} for this {EnumDescriptor}. + * + * @return [EnumOptions] + */ +static VALUE EnumDescriptor_options(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size); + VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return enum_options; +} + +/* + * ruby-doc: EnumDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L349 + * EnumDescriptorProto} of this {EnumDescriptor}. + * @return [EnumDescriptorProto] + */ +static VALUE EnumDescriptor_to_proto(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_EnumDescriptorProto* proto = + upb_EnumDef_ToProto(self->enumdef, arena); + + size_t size; + const char* serialized = + google_protobuf_EnumDescriptorProto_serialize(proto, arena, &size); + + VALUE proto_class = rb_path2class("Google::Protobuf::EnumDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void EnumDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject); + rb_define_alloc_func(klass, EnumDescriptor_alloc); + rb_define_method(klass, "initialize", EnumDescriptor_initialize, 3); + rb_define_method(klass, "name", EnumDescriptor_name, 0); + rb_define_method(klass, "lookup_name", EnumDescriptor_lookup_name, 1); + rb_define_method(klass, "lookup_value", EnumDescriptor_lookup_value, 1); + rb_define_method(klass, "each", EnumDescriptor_each, 0); + rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0); + rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0); + rb_define_method(klass, "is_closed?", EnumDescriptor_is_closed, 0); + rb_define_method(klass, "options", EnumDescriptor_options, 0); + rb_define_method(klass, "to_proto", EnumDescriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cEnumDescriptor); + cEnumDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// ServiceDescriptor +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_ServiceDef* servicedef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_ServiceDef. +} ServiceDescriptor; + +static VALUE cServiceDescriptor = Qnil; + +static void ServiceDescriptor_mark(void* _self) { + ServiceDescriptor* self = _self; + rb_gc_mark(self->module); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t ServiceDescriptor_type = { + "Google::Protobuf::ServicDescriptor", + {ServiceDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static ServiceDescriptor* ruby_to_ServiceDescriptor(VALUE val) { + ServiceDescriptor* ret; + TypedData_Get_Struct(val, ServiceDescriptor, &ServiceDescriptor_type, ret); + return ret; +} + +static VALUE ServiceDescriptor_alloc(VALUE klass) { + ServiceDescriptor* self = ALLOC(ServiceDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &ServiceDescriptor_type, self); + self->servicedef = NULL; + self->module = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +/** + * ruby-doc: ServiceDescriptor + * + * A ServiceDescriptor provides information about the Protobuf definition of an + * RPC service. + */ + +/* + * call-seq: + * ServiceDescriptor.new(c_only_cookie, ptr) => ServiceDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE ServiceDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->servicedef = (const upb_ServiceDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: ServiceDescriptor#name + * + * Returns the name of this service. + * + * @return [String] + */ +static VALUE ServiceDescriptor_name(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + return rb_str_maybe_null(upb_ServiceDef_FullName(self->servicedef)); +} + +/* + * ruby-doc: ServiceDescriptor#file_descriptor + * + * Returns the {FileDescriptor} object this service belongs to. + * @return [FileDescriptor] + */ +static VALUE ServiceDescriptor_file_descriptor(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + return get_filedef_obj(self->descriptor_pool, + upb_ServiceDef_File(self->servicedef)); +} + +/* + * ruby-doc: ServiceDescriptor#each + * + * Iterates over methods in this service, yielding to the block on each one. + * + * @yield [MethodDescriptor] + * @return [nil] + */ +static VALUE ServiceDescriptor_each(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + + int n = upb_ServiceDef_MethodCount(self->servicedef); + for (int i = 0; i < n; i++) { + const upb_MethodDef* method = upb_ServiceDef_Method(self->servicedef, i); + VALUE obj = get_methoddef_obj(self->descriptor_pool, method); + rb_yield(obj); + } + return Qnil; +} + +/* + * ruby-doc: ServiceDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L901 + * ServiceOptions} for this {ServiceDescriptor}. + * + * @return [ServiceOptions] + */ +static VALUE ServiceDescriptor_options(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + const google_protobuf_ServiceOptions* opts = + upb_ServiceDef_Options(self->servicedef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_ServiceOptions_serialize(opts, arena, &size); + VALUE service_options = decode_options(_self, "ServiceOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return service_options; +} + +/* + * ruby-doc: ServiceDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L386 + * ServiceDescriptorProto} of this {ServiceDescriptor}. + * + * @return [ServiceDescriptorProto] + */ +static VALUE ServiceDescriptor_to_proto(VALUE _self) { + ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_ServiceDescriptorProto* proto = + upb_ServiceDef_ToProto(self->servicedef, arena); + size_t size; + const char* serialized = + google_protobuf_ServiceDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::ServiceDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +static void ServiceDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "ServiceDescriptor", rb_cObject); + rb_define_alloc_func(klass, ServiceDescriptor_alloc); + rb_define_method(klass, "initialize", ServiceDescriptor_initialize, 3); + rb_define_method(klass, "name", ServiceDescriptor_name, 0); + rb_define_method(klass, "each", ServiceDescriptor_each, 0); + rb_define_method(klass, "file_descriptor", ServiceDescriptor_file_descriptor, + 0); + rb_define_method(klass, "options", ServiceDescriptor_options, 0); + rb_define_method(klass, "to_proto", ServiceDescriptor_to_proto, 0); + rb_include_module(klass, rb_mEnumerable); + rb_gc_register_address(&cServiceDescriptor); + cServiceDescriptor = klass; +} + +// ----------------------------------------------------------------------------- +// MethodDescriptor +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_MethodDef* methoddef; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE module; // begins as nil + VALUE descriptor_pool; // Owns the upb_MethodDef. +} MethodDescriptor; + +static VALUE cMethodDescriptor = Qnil; + +static void MethodDescriptor_mark(void* _self) { + MethodDescriptor* self = _self; + rb_gc_mark(self->module); + rb_gc_mark(self->descriptor_pool); +} + +static const rb_data_type_t MethodDescriptor_type = { + "Google::Protobuf::MethodDescriptor", + {MethodDescriptor_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static MethodDescriptor* ruby_to_MethodDescriptor(VALUE val) { + MethodDescriptor* ret; + TypedData_Get_Struct(val, MethodDescriptor, &MethodDescriptor_type, ret); + return ret; +} + +static VALUE MethodDescriptor_alloc(VALUE klass) { + MethodDescriptor* self = ALLOC(MethodDescriptor); + VALUE ret = TypedData_Wrap_Struct(klass, &MethodDescriptor_type, self); + self->methoddef = NULL; + self->module = Qnil; + self->descriptor_pool = Qnil; + return ret; +} + +/** + * ruby-doc: MethodDescriptor + * + * A MethodDescriptor provides information about the Protobuf definition of a + * method inside an RPC service. + */ + +/* + * call-seq: + * MethodDescriptor.new(c_only_cookie, ptr) => MethodDescriptor + * + * Creates a descriptor wrapper object. May only be called from C. + */ +static VALUE MethodDescriptor_initialize(VALUE _self, VALUE cookie, + VALUE descriptor_pool, VALUE ptr) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + + if (cookie != c_only_cookie) { + rb_raise(rb_eRuntimeError, + "Descriptor objects may not be created from Ruby."); + } + + RB_OBJ_WRITE(_self, &self->descriptor_pool, descriptor_pool); + self->methoddef = (const upb_MethodDef*)NUM2ULL(ptr); + + return Qnil; +} + +/* + * ruby-doc: MethodDescriptor#name + * + * Returns the name of this method + * + * @return [String] + */ +static VALUE MethodDescriptor_name(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + return rb_str_maybe_null(upb_MethodDef_Name(self->methoddef)); +} + +/* + * ruby-doc: MethodDescriptor#options + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L927 + * MethodOptions} for this {MethodDescriptor}. + * + * @return [MethodOptions] + */ +static VALUE MethodDescriptor_options(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + const google_protobuf_MethodOptions* opts = + upb_MethodDef_Options(self->methoddef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_MethodOptions_serialize(opts, arena, &size); + VALUE method_options = decode_options(_self, "MethodOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return method_options; +} + +/* + * ruby-doc: MethodDescriptor#input_type + * + * Returns the {Descriptor} for the request message type of this method + * + * @return [Descriptor] + */ +static VALUE MethodDescriptor_input_type(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + const upb_MessageDef* type = upb_MethodDef_InputType(self->methoddef); + return get_msgdef_obj(self->descriptor_pool, type); +} + +/* + * ruby-doc: MethodDescriptor#output_type + * + * Returns the {Descriptor} for the response message type of this method + * + * @return [Descriptor] + */ +static VALUE MethodDescriptor_output_type(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + const upb_MessageDef* type = upb_MethodDef_OutputType(self->methoddef); + return get_msgdef_obj(self->descriptor_pool, type); +} + +/* + * ruby-doc: MethodDescriptor#client_streaming + * + * Returns whether or not this is a streaming request method + * + * @return [Boolean] + */ +static VALUE MethodDescriptor_client_streaming(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + return upb_MethodDef_ClientStreaming(self->methoddef) ? Qtrue : Qfalse; +} + +/* + * ruby-doc: MethodDescriptor#to_proto + * + * Returns the + * {https://github.com/protocolbuffers/protobuf/blob/v30.2/src/google/protobuf/descriptor.proto#L394 + * MethodDescriptorProto} of this {MethodDescriptor}. + * + * @return [MethodDescriptorProto] + */ +static VALUE MethodDescriptor_to_proto(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + upb_Arena* arena = upb_Arena_New(); + google_protobuf_MethodDescriptorProto* proto = + upb_MethodDef_ToProto(self->methoddef, arena); + size_t size; + const char* serialized = + google_protobuf_MethodDescriptorProto_serialize(proto, arena, &size); + VALUE proto_class = rb_path2class("Google::Protobuf::MethodDescriptorProto"); + VALUE proto_rb = + Message_decode_bytes(size, serialized, 0, proto_class, false); + upb_Arena_Free(arena); + return proto_rb; +} + +/* + * ruby-doc: MethodDescriptor#server_streaming + * + * Returns whether or not this is a streaming response method + * + * @return [Boolean] + */ +static VALUE MethodDescriptor_server_streaming(VALUE _self) { + MethodDescriptor* self = ruby_to_MethodDescriptor(_self); + return upb_MethodDef_ServerStreaming(self->methoddef) ? Qtrue : Qfalse; +} + +static void MethodDescriptor_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "MethodDescriptor", rb_cObject); + rb_define_alloc_func(klass, MethodDescriptor_alloc); + rb_define_method(klass, "initialize", MethodDescriptor_initialize, 3); + rb_define_method(klass, "name", MethodDescriptor_name, 0); + rb_define_method(klass, "options", MethodDescriptor_options, 0); + rb_define_method(klass, "input_type", MethodDescriptor_input_type, 0); + rb_define_method(klass, "output_type", MethodDescriptor_output_type, 0); + rb_define_method(klass, "client_streaming", MethodDescriptor_client_streaming, + 0); + rb_define_method(klass, "server_streaming", MethodDescriptor_server_streaming, + 0); + rb_define_method(klass, "to_proto", MethodDescriptor_to_proto, 0); + rb_gc_register_address(&cMethodDescriptor); + cMethodDescriptor = klass; +} + +static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) { + DescriptorPool* descriptor_pool = ruby_to_DescriptorPool(_descriptor_pool); + VALUE key = ULL2NUM((intptr_t)ptr); + VALUE def; + + def = rb_hash_aref(descriptor_pool->def_to_descriptor, key); + + if (ptr == NULL) { + return Qnil; + } + + if (def == Qnil) { + // Lazily create wrapper object. + VALUE args[3] = {c_only_cookie, _descriptor_pool, key}; + def = rb_class_new_instance(3, args, klass); + rb_hash_aset(descriptor_pool->def_to_descriptor, key, def); + } + + return def; +} + +static VALUE get_msgdef_obj(VALUE descriptor_pool, const upb_MessageDef* def) { + return get_def_obj(descriptor_pool, def, cDescriptor); +} + +static VALUE get_enumdef_obj(VALUE descriptor_pool, const upb_EnumDef* def) { + return get_def_obj(descriptor_pool, def, cEnumDescriptor); +} + +static VALUE get_fielddef_obj(VALUE descriptor_pool, const upb_FieldDef* def) { + return get_def_obj(descriptor_pool, def, cFieldDescriptor); +} + +static VALUE get_filedef_obj(VALUE descriptor_pool, const upb_FileDef* def) { + return get_def_obj(descriptor_pool, def, cFileDescriptor); +} + +static VALUE get_oneofdef_obj(VALUE descriptor_pool, const upb_OneofDef* def) { + return get_def_obj(descriptor_pool, def, cOneofDescriptor); +} + +static VALUE get_servicedef_obj(VALUE descriptor_pool, + const upb_ServiceDef* def) { + return get_def_obj(descriptor_pool, def, cServiceDescriptor); +} + +static VALUE get_methoddef_obj(VALUE descriptor_pool, + const upb_MethodDef* def) { + return get_def_obj(descriptor_pool, def, cMethodDescriptor); +} + +// ----------------------------------------------------------------------------- +// Shared functions +// ----------------------------------------------------------------------------- + +// Functions exposed to other modules in defs.h. + +VALUE Descriptor_DefToClass(const upb_MessageDef* m) { + const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m)); + VALUE pool = ObjectCache_Get(symtab); + PBRUBY_ASSERT(pool != Qnil); + VALUE desc_rb = get_msgdef_obj(pool, m); + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + return desc->klass; +} + +const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb) { + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + return desc->msgdef; +} + +VALUE TypeInfo_InitArg(int argc, VALUE* argv, int skip_arg) { + if (argc > skip_arg) { + if (argc > 1 + skip_arg) { + rb_raise(rb_eArgError, "Expected a maximum of %d arguments.", + skip_arg + 1); + } + return argv[skip_arg]; + } else { + return Qnil; + } +} + +TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, + VALUE* type_class, VALUE* init_arg) { + TypeInfo ret = {ruby_to_fieldtype(argv[skip_arg])}; + + if (ret.type == kUpb_CType_Message || ret.type == kUpb_CType_Enum) { + *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 2); + + if (argc < 2 + skip_arg) { + rb_raise(rb_eArgError, "Expected at least %d arguments for message/enum.", + 2 + skip_arg); + } + + VALUE klass = argv[1 + skip_arg]; + VALUE desc = MessageOrEnum_GetDescriptor(klass); + *type_class = klass; + + if (desc == Qnil) { + rb_raise(rb_eArgError, + "Type class has no descriptor. Please pass a " + "class or enum as returned by the DescriptorPool."); + } + + if (ret.type == kUpb_CType_Message) { + ret.def.msgdef = ruby_to_Descriptor(desc)->msgdef; + Message_CheckClass(klass); + } else { + PBRUBY_ASSERT(ret.type == kUpb_CType_Enum); + ret.def.enumdef = ruby_to_EnumDescriptor(desc)->enumdef; + } + } else { + *init_arg = TypeInfo_InitArg(argc, argv, skip_arg + 1); + } + + return ret; +} + +void Defs_register(VALUE module) { + DescriptorPool_register(module); + Descriptor_register(module); + FileDescriptor_register(module); + FieldDescriptor_register(module); + OneofDescriptor_register(module); + EnumDescriptor_register(module); + ServiceDescriptor_register(module); + MethodDescriptor_register(module); + + rb_gc_register_address(&c_only_cookie); + c_only_cookie = rb_class_new_instance(0, NULL, rb_cObject); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h new file mode 100755 index 0000000..931dd6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/defs.h @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_DEFS_H_ +#define RUBY_PROTOBUF_DEFS_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// ----------------------------------------------------------------------------- +// TypeInfo +// ----------------------------------------------------------------------------- + +// This bundles a upb_CType and msgdef/enumdef when appropriate. This is +// convenient for functions that need type information but cannot necessarily +// assume a upb_FieldDef will be available. +// +// For example, Google::Protobuf::Map and Google::Protobuf::RepeatedField can +// be constructed with type information alone: +// +// # RepeatedField will internally store the type information in a TypeInfo. +// Google::Protobuf::RepeatedField.new(:message, FooMessage) + +typedef struct { + upb_CType type; + union { + const upb_MessageDef* msgdef; // When type == kUpb_CType_Message + const upb_EnumDef* enumdef; // When type == kUpb_CType_Enum + } def; +} TypeInfo; + +static inline TypeInfo TypeInfo_get(const upb_FieldDef* f) { + TypeInfo ret = {upb_FieldDef_CType(f), {NULL}}; + switch (ret.type) { + case kUpb_CType_Message: + ret.def.msgdef = upb_FieldDef_MessageSubDef(f); + break; + case kUpb_CType_Enum: + ret.def.enumdef = upb_FieldDef_EnumSubDef(f); + break; + default: + break; + } + return ret; +} + +TypeInfo TypeInfo_FromClass(int argc, VALUE* argv, int skip_arg, + VALUE* type_class, VALUE* init_arg); + +static inline TypeInfo TypeInfo_from_type(upb_CType type) { + TypeInfo ret = {type}; + assert(type != kUpb_CType_Message && type != kUpb_CType_Enum); + return ret; +} + +// ----------------------------------------------------------------------------- +// Other utilities +// ----------------------------------------------------------------------------- + +VALUE Descriptor_DefToClass(const upb_MessageDef* m); + +// Returns the underlying msgdef, enumdef, or symtab (respectively) for the +// given Descriptor, EnumDescriptor, or DescriptorPool Ruby object. +const upb_EnumDef* EnumDescriptor_GetEnumDef(VALUE enum_desc_rb); +const upb_DefPool* DescriptorPool_GetSymtab(VALUE desc_pool_rb); +const upb_MessageDef* Descriptor_GetMsgDef(VALUE desc_rb); + +// Returns a upb field type for the given Ruby symbol +// (eg. :float => kUpb_CType_Float). +upb_CType ruby_to_fieldtype(VALUE type); + +// The singleton generated pool (a DescriptorPool object). +extern VALUE generated_pool; + +// Call at startup to register all types in this module. +void Defs_register(VALUE module); + +#endif // RUBY_PROTOBUF_DEFS_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb new file mode 100755 index 0000000..f97b9b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/extconf.rb @@ -0,0 +1,38 @@ +#!/usr/bin/ruby + +require 'mkmf' + +ext_name = "google/protobuf_c" + +dir_config(ext_name) + +if ENV["CC"] + RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] +end + +if ENV["CXX"] + RbConfig::CONFIG["CXX"] = RbConfig::MAKEFILE_CONFIG["CXX"] = ENV["CXX"] +end + +if ENV["LD"] + RbConfig::CONFIG["LD"] = RbConfig::MAKEFILE_CONFIG["LD"] = ENV["LD"] +end + +debug_enabled = ENV["PROTOBUF_CONFIG"] == "dbg" + +additional_c_flags = debug_enabled ? "-O0 -fno-omit-frame-pointer -fvisibility=default -g" : "-O3 -DNDEBUG -fvisibility=hidden" + +if RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/ || RUBY_PLATFORM =~ /freebsd/ + $CFLAGS += " -std=gnu99 -Wall -Wsign-compare -Wno-declaration-after-statement #{additional_c_flags}" +else + $CFLAGS += " -std=gnu99 #{additional_c_flags}" +end + +$VPATH << "$(srcdir)/third_party/utf8_range" +$INCFLAGS += " -I$(srcdir)/third_party/utf8_range" + +$srcs = ["protobuf.c", "convert.c", "defs.c", "message.c", "repeated_field.c", + "map.c", "ruby-upb.c", "utf8_range.c", "shared_convert.c", + "shared_message.c"] + +create_makefile(ext_name) diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c new file mode 100755 index 0000000..46e9146 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/glue.c @@ -0,0 +1,135 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Exposing inlined UPB functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#include "ruby-upb.h" + +upb_Arena* Arena_create() { return upb_Arena_Init(NULL, 0, &upb_alloc_global); } + +google_protobuf_FileDescriptorProto* FileDescriptorProto_parse( + const char* serialized_file_proto, size_t length, upb_Arena* arena) { + return google_protobuf_FileDescriptorProto_parse(serialized_file_proto, + length, arena); +} + +char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(enumdef); + char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, size); + return serialized; +} + +char* EnumDescriptor_serialized_to_proto(const upb_EnumDef* enumdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_EnumDescriptorProto* file_proto = + upb_EnumDef_ToProto(enumdef, arena); + char* serialized = + google_protobuf_EnumDescriptorProto_serialize(file_proto, arena, size); + return serialized; +} + +char* FileDescriptor_serialized_options(const upb_FileDef* filedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef); + char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size); + return serialized; +} + +char* FileDescriptor_serialized_to_proto(const upb_FileDef* filedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FileDescriptorProto* file_proto = + upb_FileDef_ToProto(filedef, arena); + char* serialized = + google_protobuf_FileDescriptorProto_serialize(file_proto, arena, size); + return serialized; +} + +char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size, + upb_Arena* arena) { + const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef); + char* serialized = + google_protobuf_MessageOptions_serialize(opts, arena, size); + return serialized; +} + +char* Descriptor_serialized_to_proto(const upb_MessageDef* msgdef, size_t* size, + upb_Arena* arena) { + const google_protobuf_DescriptorProto* proto = + upb_MessageDef_ToProto(msgdef, arena); + char* serialized = + google_protobuf_DescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef); + char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size); + return serialized; +} + +char* OneOfDescriptor_serialized_to_proto(const upb_OneofDef* oneofdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_OneofDescriptorProto* proto = + upb_OneofDef_ToProto(oneofdef, arena); + char* serialized = + google_protobuf_OneofDescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef); + char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size); + return serialized; +} + +char* FieldDescriptor_serialized_to_proto(const upb_FieldDef* fieldef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FieldDescriptorProto* proto = + upb_FieldDef_ToProto(fieldef, arena); + char* serialized = + google_protobuf_FieldDescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_ServiceOptions* opts = + upb_ServiceDef_Options(servicedef); + char* serialized = + google_protobuf_ServiceOptions_serialize(opts, arena, size); + return serialized; +} + +char* ServiceDescriptor_serialized_to_proto(const upb_ServiceDef* servicedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_ServiceDescriptorProto* proto = + upb_ServiceDef_ToProto(servicedef, arena); + char* serialized = + google_protobuf_ServiceDescriptorProto_serialize(proto, arena, size); + return serialized; +} + +char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef, + size_t* size, upb_Arena* arena) { + const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef); + char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size); + return serialized; +} + +char* MethodDescriptor_serialized_to_proto(const upb_MethodDef* methodef, + size_t* size, upb_Arena* arena) { + const google_protobuf_MethodDescriptorProto* proto = + upb_MethodDef_ToProto(methodef, arena); + char* serialized = + google_protobuf_MethodDescriptorProto_serialize(proto, arena, size); + return serialized; +}
\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c new file mode 100755 index 0000000..4ad3995 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.c @@ -0,0 +1,768 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "convert.h" +#include "defs.h" +#include "message.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// Basic map operations on top of upb_Map. +// +// Note that we roll our own `Map` container here because, as for +// `RepeatedField`, we want a strongly-typed container. This is so that any user +// errors due to incorrect map key or value types are raised as close as +// possible to the error site, rather than at some deferred point (e.g., +// serialization). +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// Map container type. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_Map* map; // Can convert to mutable when non-frozen. + upb_CType key_type; + TypeInfo value_type_info; + VALUE value_type_class; + VALUE arena; +} Map; + +static void Map_mark(void* _self) { + Map* self = _self; + rb_gc_mark(self->value_type_class); + rb_gc_mark(self->arena); +} + +static size_t Map_memsize(const void* _self) { return sizeof(Map); } + +const rb_data_type_t Map_type = { + "Google::Protobuf::Map", + {Map_mark, RUBY_DEFAULT_FREE, Map_memsize}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +VALUE cMap; + +static Map* ruby_to_Map(VALUE _self) { + Map* self; + TypedData_Get_Struct(_self, Map, &Map_type, self); + return self; +} + +static VALUE Map_alloc(VALUE klass) { + Map* self = ALLOC(Map); + self->map = NULL; + self->value_type_class = Qnil; + self->value_type_info.def.msgdef = NULL; + self->arena = Qnil; + return TypedData_Wrap_Struct(klass, &Map_type, self); +} + +VALUE Map_GetRubyWrapper(const upb_Map* map, upb_CType key_type, + TypeInfo value_type, VALUE arena) { + PBRUBY_ASSERT(map); + PBRUBY_ASSERT(arena != Qnil); + + VALUE val = ObjectCache_Get(map); + + if (val == Qnil) { + val = Map_alloc(cMap); + Map* self; + TypedData_Get_Struct(val, Map, &Map_type, self); + self->map = map; + self->arena = arena; + self->key_type = key_type; + self->value_type_info = value_type; + if (self->value_type_info.type == kUpb_CType_Message) { + const upb_MessageDef* val_m = self->value_type_info.def.msgdef; + self->value_type_class = Descriptor_DefToClass(val_m); + } + return ObjectCache_TryAdd(map, val); + } + return val; +} + +static VALUE Map_new_this_type(Map* from) { + VALUE arena_rb = Arena_new(); + upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type, + from->value_type_info.type); + VALUE ret = + Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb); + PBRUBY_ASSERT(ruby_to_Map(ret)->value_type_class == from->value_type_class); + return ret; +} + +static TypeInfo Map_keyinfo(Map* self) { + TypeInfo ret; + ret.type = self->key_type; + ret.def.msgdef = NULL; + return ret; +} + +static upb_Map* Map_GetMutable(VALUE _self) { + const upb_Map* map = ruby_to_Map(_self)->map; + Protobuf_CheckNotFrozen(_self, upb_Map_IsFrozen(map)); + return (upb_Map*)map; +} + +VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type, + TypeInfo val_info) { + VALUE hash = rb_hash_new(); + TypeInfo key_info = TypeInfo_from_type(key_type); + + if (!map) return hash; + + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(map, &key, &val, &iter)) { + VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil); + VALUE val_val = Scalar_CreateHash(val, val_info); + rb_hash_aset(hash, key_val, val_val); + } + + return hash; +} + +VALUE Map_deep_copy(VALUE obj) { + Map* self = ruby_to_Map(obj); + VALUE new_arena_rb = Arena_new(); + upb_Arena* arena = Arena_get(new_arena_rb); + upb_Map* new_map = + upb_Map_New(arena, self->key_type, self->value_type_info.type); + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + upb_MessageValue val_copy = + Msgval_DeepCopy(val, self->value_type_info, arena); + upb_Map_Set(new_map, key, val_copy, arena); + } + + return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info, + new_arena_rb); +} + +const upb_Map* Map_GetUpbMap(VALUE val, const upb_FieldDef* field, + upb_Arena* arena) { + const upb_FieldDef* key_field = map_field_key(field); + const upb_FieldDef* value_field = map_field_value(field); + TypeInfo value_type_info = TypeInfo_get(value_field); + Map* self; + + if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || + RTYPEDDATA_TYPE(val) != &Map_type) { + rb_raise(cTypeError, "Expected Map instance"); + } + + self = ruby_to_Map(val); + if (self->key_type != upb_FieldDef_CType(key_field)) { + rb_raise(cTypeError, "Map key type does not match field's key type"); + } + if (self->value_type_info.type != value_type_info.type) { + rb_raise(cTypeError, "Map value type does not match field's value type"); + } + if (self->value_type_info.def.msgdef != value_type_info.def.msgdef) { + rb_raise(cTypeError, "Map value type has wrong message/enum class"); + } + + Arena_fuse(self->arena, arena); + return self->map; +} + +void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type, + TypeInfo val_type) { + bool first = true; + TypeInfo key_type_info = {key_type}; + StringBuilder_Printf(b, "{"); + if (map) { + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(map, &key, &val, &iter)) { + if (first) { + first = false; + } else { + StringBuilder_Printf(b, ", "); + } + StringBuilder_PrintMsgval(b, key, key_type_info); + StringBuilder_Printf(b, "=>"); + StringBuilder_PrintMsgval(b, val, val_type); + } + } + StringBuilder_Printf(b, "}"); +} + +static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) { + Map* self = ruby_to_Map(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue key_val = + Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); + upb_MessageValue val_val = + Convert_RubyToUpb(val, "", self->value_type_info, arena); + upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena); + return ST_CONTINUE; +} + +// Used only internally -- shared by #merge and #initialize. +static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { + if (TYPE(hashmap) == T_HASH) { + rb_hash_foreach(hashmap, merge_into_self_callback, _self); + } else if (RB_TYPE_P(hashmap, T_DATA) && RTYPEDDATA_P(hashmap) && + RTYPEDDATA_TYPE(hashmap) == &Map_type) { + Map* self = ruby_to_Map(_self); + Map* other = ruby_to_Map(hashmap); + upb_Arena* arena = Arena_get(self->arena); + upb_Map* self_map = Map_GetMutable(_self); + + Arena_fuse(other->arena, arena); + + if (self->key_type != other->key_type || + self->value_type_info.type != other->value_type_info.type || + self->value_type_class != other->value_type_class) { + rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types"); + } + + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(other->map, &key, &val, &iter)) { + upb_Map_Set(self_map, key, val, arena); + } + } else { + rb_raise(rb_eArgError, "Unknown type merging into Map"); + } + return _self; +} + +/** + * ruby-doc: Map + * + * This class represents a Protobuf Map. It is largely automatically transformed + * to and from a Ruby hash. + */ + +/* + * ruby-doc: Map#initialize + * + * Allocates a new Map container. This constructor may be called with 2, 3, or 4 + * arguments. The first two arguments are always present and are symbols (taking + * on the same values as field-type symbols in message descriptors) that + * indicate the type of the map key and value fields. + * + * The supported key types are: :int32, :int64, :uint32, :uint64, :bool, + * :string, :bytes. + * + * The supported value types are: :int32, :int64, :uint32, :uint64, :bool, + * :string, :bytes, :enum, :message. + * + * The third argument, value_typeclass, must be present if value_type is :enum + * or :message. As in RepeatedField#new, this argument must be a message class + * (for :message) or enum module (for :enum). + * + * The last argument, if present, provides initial content for map. Note that + * this may be an ordinary Ruby hashmap or another Map instance with identical + * key and value types. Also note that this argument may be present whether or + * not value_typeclass is present (and it is unambiguously separate from + * value_typeclass because value_typeclass's presence is strictly determined by + * value_type). The contents of this initial hashmap or Map instance are + * shallow-copied into the new Map: the original map is unmodified, but + * references to underlying objects will be shared if the value type is a + * message type. + * + * @param key_type [Symbol] + * @param value_type [Symbol] + * @param value_typeclass [Class<AbstractMessage>,Module] + * @paramdefault value_typeclass nil + * @param init_hashmap [Hash,Map] + * @paramdefault init_hashmap {} + */ +static VALUE Map_init(int argc, VALUE* argv, VALUE _self) { + Map* self = ruby_to_Map(_self); + VALUE init_arg; + + // We take either two args (:key_type, :value_type), three args (:key_type, + // :value_type, "ValueMessageType"), or four args (the above plus an initial + // hashmap). + if (argc < 2 || argc > 4) { + rb_raise(rb_eArgError, "Map constructor expects 2, 3 or 4 arguments."); + } + + self->key_type = ruby_to_fieldtype(argv[0]); + self->value_type_info = + TypeInfo_FromClass(argc, argv, 1, &self->value_type_class, &init_arg); + self->arena = Arena_new(); + + // Check that the key type is an allowed type. + switch (self->key_type) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Bool: + case kUpb_CType_String: + case kUpb_CType_Bytes: + // These are OK. + break; + default: + rb_raise(rb_eArgError, "Invalid key type for map."); + } + + self->map = upb_Map_New(Arena_get(self->arena), self->key_type, + self->value_type_info.type); + VALUE stored = ObjectCache_TryAdd(self->map, _self); + (void)stored; + PBRUBY_ASSERT(stored == _self); + + if (init_arg != Qnil) { + Map_merge_into_self(_self, init_arg); + } + + return Qnil; +} + +/* + * ruby-doc: Map#each + * + * Invokes &block on each |key, value| pair in the map, in unspecified order. + * Note that Map also includes Enumerable; map thus acts like a normal Ruby + * sequence. + * + * @yield [Object, Object] + * @return [nil] + */ +static VALUE Map_each(VALUE _self) { + Map* self = ruby_to_Map(_self); + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); + VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); + rb_yield_values(2, key_val, val_val); + } + + return Qnil; +} + +/* + * ruby-doc: Map#keys + * + * Returns the list of keys contained in the map, in unspecified order. + * + * @return [Array<Object>] + */ +static VALUE Map_keys(VALUE _self) { + Map* self = ruby_to_Map(_self); + size_t iter = kUpb_Map_Begin; + VALUE ret = rb_ary_new(); + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena); + rb_ary_push(ret, key_val); + } + + return ret; +} + +/* + * ruby-doc: Map#values + * + * Returns the list of values contained in the map, in unspecified order. + * + * @return [Array<Object>] + */ +static VALUE Map_values(VALUE _self) { + Map* self = ruby_to_Map(_self); + size_t iter = kUpb_Map_Begin; + VALUE ret = rb_ary_new(); + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena); + rb_ary_push(ret, val_val); + } + + return ret; +} + +/* + * ruby-doc: Map#[] + * + * Accesses the element at the given key. Throws an exception if the key type is + * incorrect. Returns nil when the key is not present in the map. + * + * @param key [Object] + * @return [Object] + */ +static VALUE Map_index(VALUE _self, VALUE key) { + Map* self = ruby_to_Map(_self); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val; + + if (upb_Map_Get(self->map, key_upb, &val)) { + return Convert_UpbToRuby(val, self->value_type_info, self->arena); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Map#[]= + * + * Inserts or overwrites the value at the given key with the given new value. + * Throws an exception if the key type is incorrect. Returns the new value that + * was just inserted. + * + * @param key [Object] + * @param value [Object] + * @return [Object] + */ +static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) { + Map* self = ruby_to_Map(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val_upb = + Convert_RubyToUpb(val, "", self->value_type_info, arena); + + upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena); + + return val; +} + +/* + * ruby-doc: Map#has_key? + * + * Returns true if the given key is present in the map. Throws an exception if + * the key has the wrong type. + * + * @param key [Object] + * @return [Boolean] + */ +static VALUE Map_has_key(VALUE _self, VALUE key) { + Map* self = ruby_to_Map(_self); + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + + if (upb_Map_Get(self->map, key_upb, NULL)) { + return Qtrue; + } else { + return Qfalse; + } +} + +/* + * ruby-doc: Map#delete + * + * Deletes the value at the given key, if any, returning either the old value or + * nil if none was present. Throws an exception if the key is of the wrong type. + * + * @param key [Object] + * @return [Object] + */ +static VALUE Map_delete(VALUE _self, VALUE key) { + upb_Map* map = Map_GetMutable(_self); + Map* self = ruby_to_Map(_self); + + upb_MessageValue key_upb = + Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + upb_MessageValue val_upb; + + if (upb_Map_Delete(map, key_upb, &val_upb)) { + return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Map#clear + * + * Removes all entries from the map. + * + * @return [nil] + */ +static VALUE Map_clear(VALUE _self) { + upb_Map_Clear(Map_GetMutable(_self)); + return Qnil; +} + +/* + * ruby-doc: Map#length + * + * Returns the number of entries (key-value pairs) in the map. + * + * @return [Integer] + */ +static VALUE Map_length(VALUE _self) { + Map* self = ruby_to_Map(_self); + return ULL2NUM(upb_Map_Size(self->map)); +} + +/* + * ruby-doc: Map#dup + * + * Duplicates this map with a shallow copy. References to all non-primitive + * element objects (e.g., submessages) are shared. + * + * @return [Map] + */ +static VALUE Map_dup(VALUE _self) { + Map* self = ruby_to_Map(_self); + VALUE new_map_rb = Map_new_this_type(self); + Map* new_self = ruby_to_Map(new_map_rb); + size_t iter = kUpb_Map_Begin; + upb_Arena* arena = Arena_get(new_self->arena); + upb_Map* new_map = Map_GetMutable(new_map_rb); + + Arena_fuse(self->arena, arena); + + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + upb_Map_Set(new_map, key, val, arena); + } + + return new_map_rb; +} + +/* + * ruby-doc: Map#== + * + * Compares this map to another. Maps are equal if they have identical key sets, + * and for each key, the values in both maps compare equal. Elements are + * compared as per normal Ruby semantics, by calling their :== methods (or + * performing a more efficient comparison for primitive types). + * + * Maps with dissimilar key types or value types/typeclasses are never equal, + * even if value comparison (for example, between integers and floats) would + * have otherwise indicated that every element has equal value. + * + * @param other [Map] + * @return [Boolean] + */ +VALUE Map_eq(VALUE _self, VALUE _other) { + Map* self = ruby_to_Map(_self); + Map* other; + + // Allow comparisons to Ruby hashmaps by converting to a temporary Map + // instance. Slow, but workable. + if (TYPE(_other) == T_HASH) { + VALUE other_map = Map_new_this_type(self); + Map_merge_into_self(other_map, _other); + _other = other_map; + } + + other = ruby_to_Map(_other); + + if (self == other) { + return Qtrue; + } + if (self->key_type != other->key_type || + self->value_type_info.type != other->value_type_info.type || + self->value_type_class != other->value_type_class) { + return Qfalse; + } + if (upb_Map_Size(self->map) != upb_Map_Size(other->map)) { + return Qfalse; + } + + // For each member of self, check that an equal member exists at the same key + // in other. + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + upb_MessageValue other_val; + if (!upb_Map_Get(other->map, key, &other_val)) { + // Not present in other map. + return Qfalse; + } + if (!Msgval_IsEqual(val, other_val, self->value_type_info)) { + // Present but different value. + return Qfalse; + } + } + + return Qtrue; +} + +/* + * ruby-doc: Map#frozen? + * + * Returns true if the map is frozen in either Ruby or the underlying + * representation. Freezes the Ruby map object if it is not already frozen in + * Ruby but it is frozen in the underlying representation. + * + * @return [Boolean] + */ +VALUE Map_frozen(VALUE _self) { + Map* self = ruby_to_Map(_self); + if (!upb_Map_IsFrozen(self->map)) { + PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self)); + return Qfalse; + } + + // Lazily freeze the Ruby wrapper. + if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self); + return Qtrue; +} + +/* + * ruby-doc: Map#freeze + * + * Freezes the map object. We have to intercept this so we can freeze the + * underlying representation, not just the Ruby wrapper. + * + * @return [self] + */ +VALUE Map_freeze(VALUE _self) { + Map* self = ruby_to_Map(_self); + if (RB_OBJ_FROZEN(_self)) { + PBRUBY_ASSERT(upb_Map_IsFrozen(self->map)); + return _self; + } + + if (!upb_Map_IsFrozen(self->map)) { + if (self->value_type_info.type == kUpb_CType_Message) { + upb_Map_Freeze( + Map_GetMutable(_self), + upb_MessageDef_MiniTable(self->value_type_info.def.msgdef)); + } else { + upb_Map_Freeze(Map_GetMutable(_self), NULL); + } + } + + RB_OBJ_FREEZE(_self); + + return _self; +} + +VALUE Map_EmptyFrozen(const upb_FieldDef* f) { + PBRUBY_ASSERT(upb_FieldDef_IsMap(f)); + VALUE val = ObjectCache_Get(f); + + if (val == Qnil) { + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); + TypeInfo value_type_info = TypeInfo_get(val_f); + val = Map_alloc(cMap); + Map* self; + TypedData_Get_Struct(val, Map, &Map_type, self); + self->arena = Arena_new(); + self->map = + upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type); + self->key_type = key_type; + self->value_type_info = value_type_info; + if (self->value_type_info.type == kUpb_CType_Message) { + const upb_MessageDef* val_m = value_type_info.def.msgdef; + self->value_type_class = Descriptor_DefToClass(val_m); + } + return ObjectCache_TryAdd(f, Map_freeze(val)); + } + PBRUBY_ASSERT(RB_OBJ_FROZEN(val)); + PBRUBY_ASSERT(upb_Map_IsFrozen(ruby_to_Map(val)->map)); + return val; +} + +/* + * ruby-doc: Map#hash + * + * Returns a hash value based on this map's contents. + * + * @return [Integer] + */ +VALUE Map_hash(VALUE _self) { + Map* self = ruby_to_Map(_self); + uint64_t hash = 0; + + size_t iter = kUpb_Map_Begin; + TypeInfo key_info = {self->key_type}; + upb_MessageValue key, val; + while (upb_Map_Next(self->map, &key, &val, &iter)) { + hash += Msgval_GetHash(key, key_info, 0); + hash += Msgval_GetHash(val, self->value_type_info, 0); + } + + return LL2NUM(hash); +} + +/* + * ruby-doc: Map#to_h + * + * Returns a Ruby Hash object containing all the values within the map + * + * @return [Hash] + */ +VALUE Map_to_h(VALUE _self) { + Map* self = ruby_to_Map(_self); + return Map_CreateHash(self->map, self->key_type, self->value_type_info); +} + +/* + * ruby-doc: Map#inspect + * + * Returns a string representing this map's elements. It will be formatted as + * "{key => value, key => value, ...}", with each key and value string + * representation computed by its own #inspect method. + * + * @return [String] + */ +VALUE Map_inspect(VALUE _self) { + Map* self = ruby_to_Map(_self); + + StringBuilder* builder = StringBuilder_New(); + Map_Inspect(builder, self->map, self->key_type, self->value_type_info); + VALUE ret = StringBuilder_ToRubyString(builder); + StringBuilder_Free(builder); + return ret; +} + +/* + * ruby-doc: Map#merge + * + * Copies key/value pairs from other_map into a copy of this map. If a key is + * set in other_map and this map, the value from other_map overwrites the value + * in the new copy of this map. Returns the new copy of this map with merged + * contents. + * + * @param other_map [Map] + * @return [Map] + */ +static VALUE Map_merge(VALUE _self, VALUE hashmap) { + VALUE dupped = Map_dup(_self); + return Map_merge_into_self(dupped, hashmap); +} + +void Map_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "Map", rb_cObject); + rb_define_alloc_func(klass, Map_alloc); + rb_gc_register_address(&cMap); + cMap = klass; + + rb_define_method(klass, "initialize", Map_init, -1); + rb_define_method(klass, "each", Map_each, 0); + rb_define_method(klass, "keys", Map_keys, 0); + rb_define_method(klass, "values", Map_values, 0); + rb_define_method(klass, "[]", Map_index, 1); + rb_define_method(klass, "[]=", Map_index_set, 2); + rb_define_method(klass, "has_key?", Map_has_key, 1); + rb_define_method(klass, "delete", Map_delete, 1); + rb_define_method(klass, "clear", Map_clear, 0); + rb_define_method(klass, "length", Map_length, 0); + rb_define_method(klass, "size", Map_length, 0); + rb_define_method(klass, "dup", Map_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", Map_dup, 0); + rb_define_method(klass, "==", Map_eq, 1); + rb_define_method(klass, "freeze", Map_freeze, 0); + rb_define_method(klass, "frozen?", Map_frozen, 0); + rb_define_method(klass, "hash", Map_hash, 0); + rb_define_method(klass, "to_h", Map_to_h, 0); + rb_define_method(klass, "inspect", Map_inspect, 0); + rb_define_method(klass, "merge", Map_merge, 1); + rb_include_module(klass, rb_mEnumerable); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h new file mode 100755 index 0000000..58e8c25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/map.h @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_MAP_H_ +#define RUBY_PROTOBUF_MAP_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Returns a frozen sentinel Ruby wrapper object for an empty upb_Map with the +// key and value types specified by the field. Creates one if it doesn't exist. +VALUE Map_EmptyFrozen(const upb_FieldDef* f); + +// Returns a Ruby wrapper object for the given map, which will be created if +// one does not exist already. +VALUE Map_GetRubyWrapper(const upb_Map *map, upb_CType key_type, + TypeInfo value_type, VALUE arena); + +// Gets the underlying upb_Map for this Ruby map object, which must have +// key/value type that match |field|. If this is not a map or the type doesn't +// match, raises an exception. +const upb_Map *Map_GetUpbMap(VALUE val, const upb_FieldDef *field, + upb_Arena *arena); + +// Implements #inspect for this map by appending its contents to |b|. +void Map_Inspect(StringBuilder *b, const upb_Map *map, upb_CType key_type, + TypeInfo val_type); + +// Returns a new Hash object containing the contents of this Map. +VALUE Map_CreateHash(const upb_Map *map, upb_CType key_type, TypeInfo val_info); + +// Returns a deep copy of this Map object. +VALUE Map_deep_copy(VALUE obj); + +// Ruby class of Google::Protobuf::Map. +extern VALUE cMap; + +// Call at startup to register all types in this module. +void Map_register(VALUE module); + +// Recursively freeze map +VALUE Map_freeze(VALUE _self); + +#endif // RUBY_PROTOBUF_MAP_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c new file mode 100755 index 0000000..93b9c7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.c @@ -0,0 +1,1462 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "message.h" + +#include "convert.h" +#include "defs.h" +#include "map.h" +#include "protobuf.h" +#include "repeated_field.h" +#include "shared_message.h" + +static VALUE cParseError = Qnil; +static VALUE cAbstractMessage = Qnil; +static ID descriptor_instancevar_interned; + +static VALUE initialize_rb_class_with_no_args(VALUE klass) { + return rb_funcall(klass, rb_intern("new"), 0); +} + +VALUE MessageOrEnum_GetDescriptor(VALUE klass) { + return rb_ivar_get(klass, descriptor_instancevar_interned); +} + +// ----------------------------------------------------------------------------- +// Class/module creation from msgdefs and enumdefs, respectively. +// ----------------------------------------------------------------------------- + +typedef struct { + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE arena; + const upb_Message* msg; // Can get as mutable when non-frozen. + const upb_MessageDef* + msgdef; // kept alive by self.class.descriptor reference. +} Message; + +static void Message_mark(void* _self) { + Message* self = (Message*)_self; + rb_gc_mark(self->arena); +} + +static size_t Message_memsize(const void* _self) { return sizeof(Message); } + +static rb_data_type_t Message_type = { + "Google::Protobuf::Message", + {Message_mark, RUBY_DEFAULT_FREE, Message_memsize}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static Message* ruby_to_Message(VALUE msg_rb) { + Message* msg; + TypedData_Get_Struct(msg_rb, Message, &Message_type, msg); + return msg; +} + +static VALUE Message_alloc(VALUE klass) { + VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned); + Message* msg = ALLOC(Message); + VALUE ret; + + msg->msgdef = Descriptor_GetMsgDef(descriptor); + msg->arena = Qnil; + msg->msg = NULL; + + ret = TypedData_Wrap_Struct(klass, &Message_type, msg); + rb_ivar_set(ret, descriptor_instancevar_interned, descriptor); + + return ret; +} + +const upb_Message* Message_Get(VALUE msg_rb, const upb_MessageDef** m) { + Message* msg = ruby_to_Message(msg_rb); + if (m) *m = msg->msgdef; + return msg->msg; +} + +upb_Message* Message_GetMutable(VALUE msg_rb, const upb_MessageDef** m) { + const upb_Message* upb_msg = Message_Get(msg_rb, m); + Protobuf_CheckNotFrozen(msg_rb, upb_Message_IsFrozen(upb_msg)); + return (upb_Message*)upb_msg; +} + +void Message_InitPtr(VALUE self_, const upb_Message* msg, VALUE arena) { + PBRUBY_ASSERT(arena != Qnil); + Message* self = ruby_to_Message(self_); + self->msg = msg; + RB_OBJ_WRITE(self_, &self->arena, arena); + VALUE stored = ObjectCache_TryAdd(msg, self_); + (void)stored; + PBRUBY_ASSERT(stored == self_); +} + +VALUE Message_GetArena(VALUE msg_rb) { + Message* msg = ruby_to_Message(msg_rb); + return msg->arena; +} + +void Message_CheckClass(VALUE klass) { + if (rb_get_alloc_func(klass) != &Message_alloc) { + rb_raise(rb_eArgError, + "Message class was not returned by the DescriptorPool."); + } +} + +VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m, + VALUE arena) { + if (msg == NULL) return Qnil; + + VALUE val = ObjectCache_Get(msg); + + if (val == Qnil) { + VALUE klass = Descriptor_DefToClass(m); + val = Message_alloc(klass); + Message_InitPtr(val, msg, arena); + } + return val; +} + +void Message_PrintMessage(StringBuilder* b, const upb_Message* msg, + const upb_MessageDef* m) { + bool first = true; + int n = upb_MessageDef_FieldCount(m); + VALUE klass = Descriptor_DefToClass(m); + StringBuilder_Printf(b, "<%s: ", rb_class2name(klass)); + + for (int i = 0; i < n; i++) { + const upb_FieldDef* field = upb_MessageDef_Field(m, i); + + if (upb_FieldDef_HasPresence(field) && + !upb_Message_HasFieldByDef(msg, field)) { + continue; + } + + if (!first) { + StringBuilder_Printf(b, ", "); + } else { + first = false; + } + + upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, field); + + StringBuilder_Printf(b, "%s: ", upb_FieldDef_Name(field)); + + if (upb_FieldDef_IsMap(field)) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + TypeInfo val_info = TypeInfo_get(val_f); + Map_Inspect(b, msgval.map_val, upb_FieldDef_CType(key_f), val_info); + } else if (upb_FieldDef_IsRepeated(field)) { + RepeatedField_Inspect(b, msgval.array_val, TypeInfo_get(field)); + } else { + StringBuilder_PrintMsgval(b, msgval, TypeInfo_get(field)); + } + } + + StringBuilder_Printf(b, ">"); +} + +// Helper functions for #method_missing //////////////////////////////////////// + +enum { + METHOD_UNKNOWN = 0, + METHOD_GETTER = 1, + METHOD_SETTER = 2, + METHOD_CLEAR = 3, + METHOD_PRESENCE = 4, + METHOD_ENUM_GETTER = 5, + METHOD_WRAPPER_GETTER = 6, + METHOD_WRAPPER_SETTER = 7 +}; + +// Check if the field is a well known wrapper type +static bool IsWrapper(const upb_MessageDef* m) { + if (!m) return false; + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + return true; + default: + return false; + } +} + +static bool IsFieldWrapper(const upb_FieldDef* f) { + return IsWrapper(upb_FieldDef_MessageSubDef(f)); +} + +static bool Match(const upb_MessageDef* m, const char* name, + const upb_FieldDef** f, const upb_OneofDef** o, + const char* prefix, const char* suffix) { + size_t sp = strlen(prefix); + size_t ss = strlen(suffix); + size_t sn = strlen(name); + + if (sn <= sp + ss) return false; + + if (memcmp(name, prefix, sp) != 0 || + memcmp(name + sn - ss, suffix, ss) != 0) { + return false; + } + + return upb_MessageDef_FindByNameWithSize(m, name + sp, sn - sp - ss, f, o); +} + +static int extract_method_call(VALUE method_name, Message* self, + const upb_FieldDef** f, const upb_OneofDef** o) { + const upb_MessageDef* m = self->msgdef; + const char* name; + + Check_Type(method_name, T_SYMBOL); + name = rb_id2name(SYM2ID(method_name)); + + if (Match(m, name, f, o, "", "")) return METHOD_GETTER; + if (Match(m, name, f, o, "", "=")) return METHOD_SETTER; + if (Match(m, name, f, o, "clear_", "")) return METHOD_CLEAR; + if (Match(m, name, f, o, "has_", "?") && + (*o || (*f && upb_FieldDef_HasPresence(*f)))) { + return METHOD_PRESENCE; + } + if (Match(m, name, f, o, "", "_as_value") && *f && + !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) { + return METHOD_WRAPPER_GETTER; + } + if (Match(m, name, f, o, "", "_as_value=") && *f && + !upb_FieldDef_IsRepeated(*f) && IsFieldWrapper(*f)) { + return METHOD_WRAPPER_SETTER; + } + if (Match(m, name, f, o, "", "_const") && *f && + upb_FieldDef_CType(*f) == kUpb_CType_Enum) { + return METHOD_ENUM_GETTER; + } + + return METHOD_UNKNOWN; +} + +static VALUE Message_oneof_accessor(VALUE _self, const upb_OneofDef* o, + int accessor_type) { + Message* self = ruby_to_Message(_self); + const upb_FieldDef* oneof_field = upb_Message_WhichOneofByDef(self->msg, o); + + switch (accessor_type) { + case METHOD_PRESENCE: + return oneof_field == NULL ? Qfalse : Qtrue; + case METHOD_CLEAR: + if (oneof_field != NULL) { + upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL), + oneof_field); + } + return Qnil; + case METHOD_GETTER: + return oneof_field == NULL + ? Qnil + : ID2SYM(rb_intern(upb_FieldDef_Name(oneof_field))); + case METHOD_SETTER: + rb_raise(rb_eRuntimeError, "Oneof accessors are read-only."); + } + rb_raise(rb_eRuntimeError, "Invalid access of oneof field."); +} + +static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val, + upb_Arena* arena) { + upb_MessageValue msgval; + if (upb_FieldDef_IsMap(f)) { + msgval.map_val = Map_GetUpbMap(val, f, arena); + } else if (upb_FieldDef_IsRepeated(f)) { + msgval.array_val = RepeatedField_GetUpbArray(val, f, arena); + } else { + if (val == Qnil && + (upb_FieldDef_IsSubMessage(f) || upb_FieldDef_RealContainingOneof(f))) { + upb_Message_ClearFieldByDef(msg, f); + return; + } + msgval = + Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + } + upb_Message_SetFieldByDef(msg, f, msgval, arena); +} + +VALUE Message_getfield_frozen(const upb_Message* msg, const upb_FieldDef* f, + VALUE arena) { + upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f); + if (upb_FieldDef_IsMap(f)) { + if (msgval.map_val == NULL) { + return Map_EmptyFrozen(f); + } + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); + TypeInfo value_type_info = TypeInfo_get(val_f); + return Map_GetRubyWrapper(msgval.map_val, key_type, value_type_info, arena); + } + if (upb_FieldDef_IsRepeated(f)) { + if (msgval.array_val == NULL) { + return RepeatedField_EmptyFrozen(f); + } + return RepeatedField_GetRubyWrapper(msgval.array_val, TypeInfo_get(f), + arena); + } + VALUE ret; + if (upb_FieldDef_IsSubMessage(f)) { + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + ret = Message_GetRubyWrapper(msgval.msg_val, m, arena); + } else { + ret = Convert_UpbToRuby(msgval, TypeInfo_get(f), Qnil); + } + return ret; +} + +VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) { + Message* self = ruby_to_Message(_self); + if (upb_Message_IsFrozen(self->msg)) { + return Message_getfield_frozen(self->msg, f, self->arena); + } + upb_Message* msg = Message_GetMutable(_self, NULL); + upb_Arena* arena = Arena_get(self->arena); + if (upb_FieldDef_IsMap(f)) { + upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + const upb_FieldDef* key_f = map_field_key(f); + const upb_FieldDef* val_f = map_field_value(f); + upb_CType key_type = upb_FieldDef_CType(key_f); + TypeInfo value_type_info = TypeInfo_get(val_f); + return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena); + } else if (upb_FieldDef_IsRepeated(f)) { + upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; + return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena); + } else if (upb_FieldDef_IsSubMessage(f)) { + if (!upb_Message_HasFieldByDef(msg, f)) return Qnil; + upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + return Message_GetRubyWrapper(submsg, m, self->arena); + } else { + upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f); + return Convert_UpbToRuby(msgval, TypeInfo_get(f), self->arena); + } +} + +static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f, + int accessor_type, int argc, VALUE* argv) { + upb_Arena* arena = Arena_get(Message_GetArena(_self)); + + switch (accessor_type) { + case METHOD_SETTER: + Message_setfield(Message_GetMutable(_self, NULL), f, argv[1], arena); + return Qnil; + case METHOD_CLEAR: + upb_Message_ClearFieldByDef(Message_GetMutable(_self, NULL), f); + return Qnil; + case METHOD_PRESENCE: + if (!upb_FieldDef_HasPresence(f)) { + rb_raise(rb_eRuntimeError, "Field does not have presence."); + } + return upb_Message_HasFieldByDef(Message_Get(_self, NULL), f) ? Qtrue + : Qfalse; + case METHOD_WRAPPER_GETTER: { + Message* self = ruby_to_Message(_self); + if (upb_Message_HasFieldByDef(self->msg, f)) { + PBRUBY_ASSERT(upb_FieldDef_IsSubMessage(f) && + !upb_FieldDef_IsRepeated(f)); + upb_MessageValue wrapper = upb_Message_GetFieldByDef(self->msg, f); + const upb_MessageDef* wrapper_m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* value_f = + upb_MessageDef_FindFieldByNumber(wrapper_m, 1); + upb_MessageValue value = + upb_Message_GetFieldByDef(wrapper.msg_val, value_f); + return Convert_UpbToRuby(value, TypeInfo_get(value_f), self->arena); + } else { + return Qnil; + } + } + case METHOD_WRAPPER_SETTER: { + upb_Message* msg = Message_GetMutable(_self, NULL); + if (argv[1] == Qnil) { + upb_Message_ClearFieldByDef(msg, f); + } else { + const upb_FieldDef* val_f = + upb_MessageDef_FindFieldByNumber(upb_FieldDef_MessageSubDef(f), 1); + upb_MessageValue msgval = Convert_RubyToUpb( + argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena); + upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg; + upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena); + } + return Qnil; + } + case METHOD_ENUM_GETTER: { + upb_MessageValue msgval = + upb_Message_GetFieldByDef(Message_Get(_self, NULL), f); + + if (upb_FieldDef_IsRepeated(f)) { + // Map repeated fields to a new type with ints + VALUE arr = rb_ary_new(); + size_t i, n = upb_Array_Size(msgval.array_val); + for (i = 0; i < n; i++) { + upb_MessageValue elem = upb_Array_Get(msgval.array_val, i); + rb_ary_push(arr, INT2NUM(elem.int32_val)); + } + return arr; + } else { + return INT2NUM(msgval.int32_val); + } + } + case METHOD_GETTER: + return Message_getfield(_self, f); + default: + rb_raise(rb_eRuntimeError, "Internal error, no such accessor: %d", + accessor_type); + } +} + +/* + * ruby-doc: AbstractMessage + * + * The {AbstractMessage} class is the parent class for all Protobuf messages, + * and is generated from C code. + * + * For any field whose name does not conflict with a built-in method, an + * accessor is provided with the same name as the field, and a setter is + * provided with the name of the field plus the '=' suffix. Thus, given a + * message instance 'msg' with field 'foo', the following code is valid: + * + * msg.foo = 42 + * puts msg.foo + * + * This method also provides read-only accessors for oneofs. If a oneof exists + * with name 'my_oneof', then msg.my_oneof will return a Ruby symbol equal to + * the name of the field in that oneof that is currently set, or nil if none. + * + * It also provides methods of the form 'clear_fieldname' to clear the value + * of the field 'fieldname'. For basic data types, this will set the default + * value of the field. + * + * Additionally, it provides methods of the form 'has_fieldname?', which returns + * true if the field 'fieldname' is set in the message object, else false. For + * 'proto3' syntax, calling this for a basic type field will result in an error. + */ +static VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { + Message* self = ruby_to_Message(_self); + const upb_OneofDef* o; + const upb_FieldDef* f; + int accessor_type; + + if (argc < 1) { + rb_raise(rb_eArgError, "Expected method name as first argument."); + } + + accessor_type = extract_method_call(argv[0], self, &f, &o); + + if (accessor_type == METHOD_UNKNOWN) return rb_call_super(argc, argv); + + // Validate argument count. + switch (accessor_type) { + case METHOD_SETTER: + case METHOD_WRAPPER_SETTER: + if (argc != 2) { + rb_raise(rb_eArgError, "Expected 2 arguments, received %d", argc); + } + break; + default: + if (argc != 1) { + rb_raise(rb_eArgError, "Expected 1 argument, received %d", argc); + } + break; + } + + // Dispatch accessor. + if (o != NULL) { + return Message_oneof_accessor(_self, o, accessor_type); + } else { + return Message_field_accessor(_self, f, accessor_type, argc, argv); + } +} + +static VALUE Message_respond_to_missing(int argc, VALUE* argv, VALUE _self) { + Message* self = ruby_to_Message(_self); + const upb_OneofDef* o; + const upb_FieldDef* f; + int accessor_type; + + if (argc < 1) { + rb_raise(rb_eArgError, "Expected method name as first argument."); + } + + accessor_type = extract_method_call(argv[0], self, &f, &o); + + if (accessor_type == METHOD_UNKNOWN) { + return rb_call_super(argc, argv); + } else if (o != NULL) { + return accessor_type == METHOD_SETTER ? Qfalse : Qtrue; + } else { + return Qtrue; + } +} + +void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val, + upb_Arena* arena); + +typedef struct { + upb_Map* map; + TypeInfo key_type; + TypeInfo val_type; + upb_Arena* arena; +} MapInit; + +static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { + MapInit* map_init = (MapInit*)_self; + upb_MessageValue k, v; + k = Convert_RubyToUpb(key, "", map_init->key_type, NULL); + + if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) { + const upb_MiniTable* t = + upb_MessageDef_MiniTable(map_init->val_type.def.msgdef); + upb_Message* msg = upb_Message_New(t, map_init->arena); + Message_InitFromValue(msg, map_init->val_type.def.msgdef, val, + map_init->arena); + v.msg_val = msg; + } else { + v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena); + } + upb_Map_Set(map_init->map, k, v, map_init->arena); + return ST_CONTINUE; +} + +static void Map_InitFromValue(upb_Map* map, const upb_FieldDef* f, VALUE val, + upb_Arena* arena) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + if (TYPE(val) != T_HASH) { + rb_raise(rb_eArgError, + "Expected Hash object as initializer value for map field '%s' " + "(given %s).", + upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val))); + } + MapInit map_init = {map, TypeInfo_get(key_f), TypeInfo_get(val_f), arena}; + rb_hash_foreach(val, Map_initialize_kwarg, (VALUE)&map_init); +} + +static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info, + upb_Arena* arena) { + if (info.type == kUpb_CType_Message) { + upb_MessageValue msgval; + const upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef); + upb_Message* msg = upb_Message_New(t, arena); + Message_InitFromValue(msg, info.def.msgdef, val, arena); + msgval.msg_val = msg; + return msgval; + } else { + return Convert_RubyToUpb(val, "", info, arena); + } +} + +static void RepeatedField_InitFromValue(upb_Array* arr, const upb_FieldDef* f, + VALUE val, upb_Arena* arena) { + TypeInfo type_info = TypeInfo_get(f); + + if (TYPE(val) != T_ARRAY) { + rb_raise(rb_eArgError, + "Expected array as initializer value for repeated field '%s' " + "(given %s).", + upb_FieldDef_Name(f), rb_class2name(CLASS_OF(val))); + } + + for (int i = 0; i < RARRAY_LEN(val); i++) { + VALUE entry = rb_ary_entry(val, i); + upb_MessageValue msgval; + if (upb_FieldDef_IsSubMessage(f) && TYPE(entry) == T_HASH) { + msgval = MessageValue_FromValue(entry, type_info, arena); + } else { + msgval = Convert_RubyToUpb(entry, upb_FieldDef_Name(f), type_info, arena); + } + upb_Array_Append(arr, msgval, arena); + } +} + +static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f, + VALUE val, upb_Arena* arena) { + if (TYPE(val) == T_NIL) return; + + if (upb_FieldDef_IsMap(f)) { + upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + Map_InitFromValue(map, f, val, arena); + } else if (upb_FieldDef_IsRepeated(f)) { + upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; + RepeatedField_InitFromValue(arr, f, val, arena); + } else if (upb_FieldDef_IsSubMessage(f)) { + if (TYPE(val) == T_HASH) { + upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + Message_InitFromValue(submsg, upb_FieldDef_MessageSubDef(f), val, arena); + } else { + Message_setfield(msg, f, val, arena); + } + } else { + upb_MessageValue msgval = + Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + upb_Message_SetFieldByDef(msg, f, msgval, arena); + } +} + +typedef struct { + upb_Message* msg; + const upb_MessageDef* msgdef; + upb_Arena* arena; +} MsgInit; + +static int Message_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { + MsgInit* msg_init = (MsgInit*)_self; + const char* name; + + if (TYPE(key) == T_STRING) { + name = RSTRING_PTR(key); + } else if (TYPE(key) == T_SYMBOL) { + name = RSTRING_PTR(rb_id2str(SYM2ID(key))); + } else { + rb_raise(rb_eArgError, + "Expected string or symbols as hash keys when initializing proto " + "from hash."); + } + + const upb_FieldDef* f = + upb_MessageDef_FindFieldByName(msg_init->msgdef, name); + + if (f == NULL) { + rb_raise(rb_eArgError, + "Unknown field name '%s' in initialization map entry.", name); + } + + Message_InitFieldFromValue(msg_init->msg, f, val, msg_init->arena); + return ST_CONTINUE; +} + +void Message_InitFromValue(upb_Message* msg, const upb_MessageDef* m, VALUE val, + upb_Arena* arena) { + MsgInit msg_init = {msg, m, arena}; + if (TYPE(val) == T_HASH) { + rb_hash_foreach(val, Message_initialize_kwarg, (VALUE)&msg_init); + } else { + rb_raise(rb_eArgError, "Expected hash arguments or message, not %s", + rb_class2name(CLASS_OF(val))); + } +} + +/* + * ruby-doc: AbstractMessage#initialize + * + * Creates a new instance of the given message class. Keyword arguments may be + * provided with keywords corresponding to field names. + * + * @param kwargs the list of field keys and values. + */ +static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) { + Message* self = ruby_to_Message(_self); + VALUE arena_rb = Arena_new(); + upb_Arena* arena = Arena_get(arena_rb); + const upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef); + upb_Message* msg = upb_Message_New(t, arena); + + Message_InitPtr(_self, msg, arena_rb); + + if (argc == 0) { + return Qnil; + } + if (argc != 1) { + rb_raise(rb_eArgError, "Expected 0 or 1 arguments."); + } + Message_InitFromValue((upb_Message*)self->msg, self->msgdef, argv[0], arena); + return Qnil; +} + +/* + * ruby-doc: AbstractMessage#dup + * + * Performs a shallow copy of this message and returns the new copy. + * + * @return [AbstractMessage] + */ +static VALUE Message_dup(VALUE _self) { + Message* self = ruby_to_Message(_self); + VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self)); + Message* new_msg_self = ruby_to_Message(new_msg); + const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef); + upb_Message_ShallowCopy((upb_Message*)new_msg_self->msg, self->msg, m); + Arena_fuse(self->arena, Arena_get(new_msg_self->arena)); + return new_msg; +} + +/* + * ruby-doc: AbstractMessage#== + * + * Performs a deep comparison of this message with another. Messages are equal + * if they have the same type and if each field is equal according to the :== + * method's semantics (a more efficient comparison may actually be done if the + * field is of a primitive type). + * + * @param other [AbstractMessage] + * @return [Boolean] + */ +static VALUE Message_eq(VALUE _self, VALUE _other) { + if (CLASS_OF(_self) != CLASS_OF(_other)) return Qfalse; + + Message* self = ruby_to_Message(_self); + Message* other = ruby_to_Message(_other); + assert(self->msgdef == other->msgdef); + + const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef); + const int options = 0; + return upb_Message_IsEqual(self->msg, other->msg, m, options) ? Qtrue + : Qfalse; +} + +uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed) { + upb_Status status; + upb_Status_Clear(&status); + uint64_t return_value = shared_Message_Hash(msg, m, seed, &status); + if (upb_Status_IsOk(&status)) { + return return_value; + } else { + rb_raise(cParseError, "Message_Hash(): %s", + upb_Status_ErrorMessage(&status)); + } +} + +/* + * ruby-doc: AbstractMessage#hash + * + * Returns a hash value that represents this message's field values. + * + * @return [Integer] + */ +static VALUE Message_hash(VALUE _self) { + Message* self = ruby_to_Message(_self); + uint64_t hash_value = Message_Hash(self->msg, self->msgdef, 0); + // RUBY_FIXNUM_MAX should be one less than a power of 2. + assert((RUBY_FIXNUM_MAX & (RUBY_FIXNUM_MAX + 1)) == 0); + return INT2FIX(hash_value & RUBY_FIXNUM_MAX); +} + +/* + * ruby-doc: AbstractMessage#inspect + * + * Returns a human-readable string representing this message. It will be + * formatted as "<MessageType: field1: value1, field2: value2, ...>". Each + * field's value is represented according to its own #inspect method. + * + * @return [String] + */ +static VALUE Message_inspect(VALUE _self) { + Message* self = ruby_to_Message(_self); + + StringBuilder* builder = StringBuilder_New(); + Message_PrintMessage(builder, self->msg, self->msgdef); + VALUE ret = StringBuilder_ToRubyString(builder); + StringBuilder_Free(builder); + return ret; +} + +// Support functions for Message_to_h ////////////////////////////////////////// + +static VALUE RepeatedField_CreateArray(const upb_Array* arr, + TypeInfo type_info) { + int size = arr ? upb_Array_Size(arr) : 0; + VALUE ary = rb_ary_new2(size); + + for (int i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(arr, i); + VALUE val = Scalar_CreateHash(msgval, type_info); + rb_ary_push(ary, val); + } + + return ary; +} + +static VALUE Message_CreateHash(const upb_Message* msg, + const upb_MessageDef* m) { + if (!msg) return Qnil; + + VALUE hash = rb_hash_new(); + size_t iter = kUpb_Message_Begin; + const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(m)); + const upb_FieldDef* field; + upb_MessageValue val; + + while (upb_Message_Next(msg, m, pool, &field, &val, &iter)) { + if (upb_FieldDef_IsExtension(field)) { + // TODO: allow extensions once we have decided what naming scheme the + // symbol should use. eg. :"[pkg.ext]" + continue; + } + + TypeInfo type_info = TypeInfo_get(field); + VALUE msg_value; + + if (upb_FieldDef_IsMap(field)) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + upb_CType key_type = upb_FieldDef_CType(key_f); + msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f)); + } else if (upb_FieldDef_IsRepeated(field)) { + msg_value = RepeatedField_CreateArray(val.array_val, type_info); + } else { + msg_value = Scalar_CreateHash(val, type_info); + } + + VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field))); + rb_hash_aset(hash, msg_key, msg_value); + } + + return hash; +} + +VALUE Scalar_CreateHash(upb_MessageValue msgval, TypeInfo type_info) { + if (type_info.type == kUpb_CType_Message) { + return Message_CreateHash(msgval.msg_val, type_info.def.msgdef); + } else { + return Convert_UpbToRuby(msgval, type_info, Qnil); + } +} + +/* + * ruby-doc: AbstractMessage#to_h + * + * Returns the message as a Ruby Hash object, with keys as symbols. + * + * @return [Hash] + */ +static VALUE Message_to_h(VALUE _self) { + Message* self = ruby_to_Message(_self); + return Message_CreateHash(self->msg, self->msgdef); +} + +/* + * ruby-doc: AbstractMessage#frozen? + * + * Returns true if the message is frozen in either Ruby or the underlying + * representation. Freezes the Ruby message object if it is not already frozen + * in Ruby but it is frozen in the underlying representation. + * + * @return [Boolean] + */ +VALUE Message_frozen(VALUE _self) { + Message* self = ruby_to_Message(_self); + if (!upb_Message_IsFrozen(self->msg)) { + PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self)); + return Qfalse; + } + + // Lazily freeze the Ruby wrapper. + if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self); + return Qtrue; +} + +/* + * ruby-doc: AbstractMessage#freeze + * + * Freezes the message object. We have to intercept this so we can freeze the + * underlying representation, not just the Ruby wrapper. + * + * @return [self] + */ +VALUE Message_freeze(VALUE _self) { + Message* self = ruby_to_Message(_self); + if (RB_OBJ_FROZEN(_self)) { + PBRUBY_ASSERT(upb_Message_IsFrozen(self->msg)); + return _self; + } + if (!upb_Message_IsFrozen(self->msg)) { + upb_Message_Freeze(Message_GetMutable(_self, NULL), + upb_MessageDef_MiniTable(self->msgdef)); + } + RB_OBJ_FREEZE(_self); + return _self; +} + +/* + * ruby-doc: AbstractMessage#[] + * + * Accesses a field's value by field name. The provided field name should be a + * string. + * + * @param index [Integer] + * @return [Object] + */ +static VALUE Message_index(VALUE _self, VALUE field_name) { + Message* self = ruby_to_Message(_self); + const upb_FieldDef* field; + + Check_Type(field_name, T_STRING); + field = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name)); + + if (field == NULL) { + return Qnil; + } + + return Message_getfield(_self, field); +} + +/* + * ruby-doc: AbstractMessage#[]= + * + * Sets a field's value by field name. The provided field name should be a + * string. + * + * @param index [Integer] + * @param value [Object] + * @return [nil] + */ +static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) { + Message* self = ruby_to_Message(_self); + const upb_FieldDef* f; + upb_MessageValue val; + upb_Arena* arena = Arena_get(self->arena); + + Check_Type(field_name, T_STRING); + f = upb_MessageDef_FindFieldByName(self->msgdef, RSTRING_PTR(field_name)); + + if (f == NULL) { + rb_raise(rb_eArgError, "Unknown field: %s", RSTRING_PTR(field_name)); + } + + val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena); + upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val, arena); + + return Qnil; +} + +/* + * ruby-doc: AbstractMessage.decode + * + * Decodes the given data (as a string containing bytes in protocol buffers wire + * format) under the interpretation given by this message class's definition + * and returns a message object with the corresponding field values. + * @param data [String] + * @param options [Hash] + * @option recursion_limit [Integer] set to maximum decoding depth for message + * (default is 64) + * @return [AbstractMessage] + */ +static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) { + VALUE data = argv[0]; + int options = 0; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + + VALUE depth = + rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit"))); + + if (depth != Qnil && TYPE(depth) == T_FIXNUM) { + options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth)); + } + } + + if (TYPE(data) != T_STRING) { + rb_raise(rb_eArgError, "Expected string for binary protobuf data."); + } + + return Message_decode_bytes(RSTRING_LEN(data), RSTRING_PTR(data), options, + klass, /*freeze*/ false); +} + +VALUE Message_decode_bytes(size_t size, const char* bytes, int options, + VALUE klass, bool freeze) { + VALUE msg_rb = initialize_rb_class_with_no_args(klass); + Message* msg = ruby_to_Message(msg_rb); + + const upb_FileDef* file = upb_MessageDef_File(msg->msgdef); + const upb_ExtensionRegistry* extreg = + upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file)); + upb_DecodeStatus status = upb_Decode(bytes, size, (upb_Message*)msg->msg, + upb_MessageDef_MiniTable(msg->msgdef), + extreg, options, Arena_get(msg->arena)); + if (status != kUpb_DecodeStatus_Ok) { + rb_raise(cParseError, "Error occurred during parsing"); + } + if (freeze) { + Message_freeze(msg_rb); + } + return msg_rb; +} + +/* + * ruby-doc: AbstractMessage.decode_json + * + * Decodes the given data (as a string containing bytes in protocol buffers wire + * format) under the interpretration given by this message class's definition + * and returns a message object with the corresponding field values. + * + * @param data [String] + * @param options [Hash] + * @option ignore_unknown_fields [Boolean] set true to ignore unknown fields + * (default is to raise an error) + * @return [AbstractMessage] + */ +static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { + VALUE data = argv[0]; + int options = 0; + upb_Status status; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + + if (RTEST(rb_hash_lookup2( + hash_args, ID2SYM(rb_intern("ignore_unknown_fields")), Qfalse))) { + options |= upb_JsonDecode_IgnoreUnknown; + } + } + + if (TYPE(data) != T_STRING) { + rb_raise(rb_eArgError, "Expected string for JSON data."); + } + + // TODO: Check and respect string encoding. If not UTF-8, we need to + // convert, because string handlers pass data directly to message string + // fields. + + VALUE msg_rb = initialize_rb_class_with_no_args(klass); + Message* msg = ruby_to_Message(msg_rb); + + // We don't allow users to decode a wrapper type directly. + if (IsWrapper(msg->msgdef)) { + rb_raise(rb_eRuntimeError, "Cannot parse a wrapper directly."); + } + + upb_Status_Clear(&status); + const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef)); + + int result = upb_JsonDecodeDetectingNonconformance( + RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg, + msg->msgdef, pool, options, Arena_get(msg->arena), &status); + + switch (result) { + case kUpb_JsonDecodeResult_Ok: + break; + case kUpb_JsonDecodeResult_Error: + rb_raise(cParseError, "Error occurred during parsing: %s", + upb_Status_ErrorMessage(&status)); + break; + } + + return msg_rb; +} + +/* + * ruby-doc: AbstractMessage.encode + * + * Encodes the given message object to its serialized form in protocol buffers + * wire format. + * + * @param msg [AbstractMessage] + * @param options [Hash] + * @option recursion_limit [Integer] set to maximum encoding depth for message + * (default is 64) + * @return [String] + */ +static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) { + Message* msg = ruby_to_Message(argv[0]); + int options = 0; + char* data; + size_t size; + + if (CLASS_OF(argv[0]) != klass) { + rb_raise(rb_eArgError, "Message of wrong type."); + } + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + VALUE depth = + rb_hash_lookup(hash_args, ID2SYM(rb_intern("recursion_limit"))); + + if (depth != Qnil && TYPE(depth) == T_FIXNUM) { + options |= upb_DecodeOptions_MaxDepth(FIX2INT(depth)); + } + } + + upb_Arena* arena = upb_Arena_New(); + + upb_EncodeStatus status = + upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), options, + arena, &data, &size); + + if (status == kUpb_EncodeStatus_Ok) { + VALUE ret = rb_str_new(data, size); + rb_enc_associate(ret, rb_ascii8bit_encoding()); + upb_Arena_Free(arena); + return ret; + } else { + upb_Arena_Free(arena); + rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)"); + } +} + +/* + * ruby-doc: AbstractMessage.encode_json + * + * Encodes the given message object into its serialized JSON representation. + * + * @param msg [AbstractMessage] + * @param options [Hash] + * @option preserve_proto_fieldnames [Boolean] set true to use original + * fieldnames (default is to camelCase) + * @option emit_defaults [Boolean] set true to emit 0/false values (default is + * to omit them) + * @return [String] + */ +static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) { + Message* msg = ruby_to_Message(argv[0]); + int options = 0; + char buf[1024]; + size_t size; + upb_Status status; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "Expected 1 or 2 arguments."); + } + + if (argc == 2) { + VALUE hash_args = argv[1]; + if (TYPE(hash_args) != T_HASH) { + if (RTEST(rb_funcall(hash_args, rb_intern("respond_to?"), 1, + rb_str_new2("to_h")))) { + hash_args = rb_funcall(hash_args, rb_intern("to_h"), 0); + } else { + rb_raise(rb_eArgError, "Expected hash arguments."); + } + } + + if (RTEST(rb_hash_lookup2(hash_args, + ID2SYM(rb_intern("preserve_proto_fieldnames")), + Qfalse))) { + options |= upb_JsonEncode_UseProtoNames; + } + + if (RTEST(rb_hash_lookup2(hash_args, ID2SYM(rb_intern("emit_defaults")), + Qfalse))) { + options |= upb_JsonEncode_EmitDefaults; + } + + if (RTEST(rb_hash_lookup2(hash_args, + ID2SYM(rb_intern("format_enums_as_integers")), + Qfalse))) { + options |= upb_JsonEncode_FormatEnumsAsIntegers; + } + } + + upb_Status_Clear(&status); + const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef)); + size = upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf, sizeof(buf), + &status); + + if (!upb_Status_IsOk(&status)) { + rb_raise(cParseError, "Error occurred during encoding: %s", + upb_Status_ErrorMessage(&status)); + } + + VALUE ret; + if (size >= sizeof(buf)) { + char* buf2 = malloc(size + 1); + upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf2, size + 1, + &status); + ret = rb_str_new(buf2, size); + free(buf2); + } else { + ret = rb_str_new(buf, size); + } + + rb_enc_associate(ret, rb_utf8_encoding()); + return ret; +} + +/* + * ruby-doc: AbstractMessage.descriptor + * + * Class method that returns the Descriptor instance corresponding to this + * message class's type. + * + * @return [Descriptor] + */ +static VALUE Message_descriptor(VALUE klass) { + return rb_ivar_get(klass, descriptor_instancevar_interned); +} + +VALUE build_class_from_descriptor(VALUE descriptor) { + const char* name; + VALUE klass; + + name = upb_MessageDef_FullName(Descriptor_GetMsgDef(descriptor)); + if (name == NULL) { + rb_raise(rb_eRuntimeError, "Descriptor does not have assigned name."); + } + + klass = rb_define_class_id( + // Docs say this parameter is ignored. User will assign return value to + // their own toplevel constant class name. + rb_intern("Message"), cAbstractMessage); + rb_ivar_set(klass, descriptor_instancevar_interned, descriptor); + return klass; +} + +/* ruby-doc: Enum + * + * There isn't really a concrete `Enum` module generated by Protobuf. Instead, + * you can use this documentation as an indicator of methods that are defined on + * each `Enum` module that is generated. E.g. if you have: + * + * enum my_enum_type + * + * in your Proto file and generate Ruby code, a module + * called `MyEnumType` will be generated with the following methods available. + */ + +/* + * ruby-doc: Enum.lookup + * + * This module method, provided on each generated enum module, looks up an enum + * value by number and returns its name as a Ruby symbol, or nil if not found. + * + * @param number [Integer] + * @return [String] + */ +static VALUE enum_lookup(VALUE self, VALUE number) { + int32_t num = NUM2INT(number); + VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned); + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e, num); + if (ev) { + return ID2SYM(rb_intern(upb_EnumValueDef_Name(ev))); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Enum.resolve + * + * This module method, provided on each generated enum module, looks up an enum + * value by name (as a Ruby symbol) and returns its name, or nil if not found. + * + * @param name [String] + * @return [Integer] + */ +static VALUE enum_resolve(VALUE self, VALUE sym) { + const char* name = rb_id2name(SYM2ID(sym)); + VALUE desc = rb_ivar_get(self, descriptor_instancevar_interned); + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(desc); + const upb_EnumValueDef* ev = upb_EnumDef_FindValueByName(e, name); + if (ev) { + return INT2NUM(upb_EnumValueDef_Number(ev)); + } else { + return Qnil; + } +} + +/* + * ruby-doc: Enum.descriptor + * + * This module method, provided on each generated enum module, returns the + * {EnumDescriptor} corresponding to this enum type. + * + * @return [EnumDescriptor] + * + */ +static VALUE enum_descriptor(VALUE self) { + return rb_ivar_get(self, descriptor_instancevar_interned); +} + +VALUE build_module_from_enumdesc(VALUE _enumdesc) { + const upb_EnumDef* e = EnumDescriptor_GetEnumDef(_enumdesc); + VALUE mod = rb_define_module_id(rb_intern(upb_EnumDef_FullName(e))); + + int n = upb_EnumDef_ValueCount(e); + for (int i = 0; i < n; i++) { + const upb_EnumValueDef* ev = upb_EnumDef_Value(e, i); + upb_Arena* arena = upb_Arena_New(); + const char* src_name = upb_EnumValueDef_Name(ev); + char* name = upb_strdup2(src_name, strlen(src_name), arena); + int32_t value = upb_EnumValueDef_Number(ev); + if (name[0] < 'A' || name[0] > 'Z') { + if (name[0] >= 'a' && name[0] <= 'z') { + name[0] -= 32; // auto capitalize + } else { + rb_warn( + "Enum value '%s' does not start with an uppercase letter " + "as is required for Ruby constants.", + name); + } + } + rb_define_const(mod, name, INT2NUM(value)); + upb_Arena_Free(arena); + } + + rb_define_singleton_method(mod, "lookup", enum_lookup, 1); + rb_define_singleton_method(mod, "resolve", enum_resolve, 1); + rb_define_singleton_method(mod, "descriptor", enum_descriptor, 0); + rb_ivar_set(mod, descriptor_instancevar_interned, _enumdesc); + + return mod; +} + +// Internal to the library; used by Google::Protobuf.deep_copy. +upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, + upb_Arena* arena) { + // Serialize and parse. + upb_Arena* tmp_arena = upb_Arena_New(); + const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); + size_t size; + + upb_Message* new_msg = upb_Message_New(layout, arena); + char* data; + + const upb_FileDef* file = upb_MessageDef_File(m); + const upb_ExtensionRegistry* extreg = + upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file)); + if (upb_Encode(msg, layout, 0, tmp_arena, &data, &size) != + kUpb_EncodeStatus_Ok || + upb_Decode(data, size, new_msg, layout, extreg, 0, arena) != + kUpb_DecodeStatus_Ok) { + upb_Arena_Free(tmp_arena); + rb_raise(cParseError, "Error occurred copying proto"); + } + + upb_Arena_Free(tmp_arena); + return new_msg; +} + +const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, + const char* name, upb_Arena* arena) { + if (value == Qnil) { + rb_raise(cTypeError, "nil message not allowed here."); + } + + VALUE klass = CLASS_OF(value); + VALUE desc_rb = rb_ivar_get(klass, descriptor_instancevar_interned); + const upb_MessageDef* val_m = + desc_rb == Qnil ? NULL : Descriptor_GetMsgDef(desc_rb); + + if (val_m != m) { + // Check for possible implicit conversions + // TODO: hash conversion? + + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Timestamp: { + // Time -> Google::Protobuf::Timestamp + const upb_MiniTable* t = upb_MessageDef_MiniTable(m); + upb_Message* msg = upb_Message_New(t, arena); + upb_MessageValue sec, nsec; + struct timespec time; + const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2); + + if (!rb_obj_is_kind_of(value, rb_cTime)) goto badtype; + + time = rb_time_timespec(value); + sec.int64_val = time.tv_sec; + nsec.int32_val = time.tv_nsec; + upb_Message_SetFieldByDef(msg, sec_f, sec, arena); + upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena); + return msg; + } + case kUpb_WellKnown_Duration: { + // Numeric -> Google::Protobuf::Duration + const upb_MiniTable* t = upb_MessageDef_MiniTable(m); + upb_Message* msg = upb_Message_New(t, arena); + upb_MessageValue sec, nsec; + const upb_FieldDef* sec_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nsec_f = upb_MessageDef_FindFieldByNumber(m, 2); + + if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype; + + sec.int64_val = NUM2LL(value); + nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000); + upb_Message_SetFieldByDef(msg, sec_f, sec, arena); + upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena); + return msg; + } + default: + badtype: + rb_raise(cTypeError, + "Invalid type %s to assign to submessage field '%s'.", + rb_class2name(CLASS_OF(value)), name); + } + } + + Message* self = ruby_to_Message(value); + Arena_fuse(self->arena, arena); + + return self->msg; +} + +static void Message_define_class(VALUE klass) { + rb_define_alloc_func(klass, Message_alloc); + + rb_require("google/protobuf/message_exts"); + rb_define_method(klass, "method_missing", Message_method_missing, -1); + rb_define_method(klass, "respond_to_missing?", Message_respond_to_missing, + -1); + rb_define_method(klass, "initialize", Message_initialize, -1); + rb_define_method(klass, "dup", Message_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", Message_dup, 0); + rb_define_method(klass, "==", Message_eq, 1); + rb_define_method(klass, "eql?", Message_eq, 1); + rb_define_method(klass, "freeze", Message_freeze, 0); + rb_define_method(klass, "frozen?", Message_frozen, 0); + rb_define_method(klass, "hash", Message_hash, 0); + rb_define_method(klass, "to_h", Message_to_h, 0); + rb_define_method(klass, "inspect", Message_inspect, 0); + rb_define_method(klass, "to_s", Message_inspect, 0); + rb_define_method(klass, "[]", Message_index, 1); + rb_define_method(klass, "[]=", Message_index_set, 2); + rb_define_singleton_method(klass, "decode", Message_decode, -1); + rb_define_singleton_method(klass, "encode", Message_encode, -1); + rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1); + rb_define_singleton_method(klass, "encode_json", Message_encode_json, -1); + rb_define_singleton_method(klass, "descriptor", Message_descriptor, 0); +} + +void Message_register(VALUE protobuf) { + cParseError = rb_const_get(protobuf, rb_intern("ParseError")); + cAbstractMessage = + rb_define_class_under(protobuf, "AbstractMessage", rb_cObject); + Message_define_class(cAbstractMessage); + rb_gc_register_address(&cAbstractMessage); + + // Ruby-interned string: "descriptor". We use this identifier to store an + // instance variable on message classes we create in order to link them back + // to their descriptors. + descriptor_instancevar_interned = rb_intern("@descriptor"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h new file mode 100755 index 0000000..1b37db5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/message.h @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_MESSAGE_H_ +#define RUBY_PROTOBUF_MESSAGE_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Gets the underlying upb_Message* and upb_MessageDef for the given Ruby +// message wrapper. Requires that |value| is indeed a message object. +const upb_Message* Message_Get(VALUE value, const upb_MessageDef** m); + +// Like Message_Get(), but checks that the object is not frozen and returns a +// mutable pointer. +upb_Message* Message_GetMutable(VALUE value, const upb_MessageDef** m); + +// Returns the Arena object for this message. +VALUE Message_GetArena(VALUE value); + +// Converts |value| into a upb_Message value of the expected upb_MessageDef +// type, raising an error if this is not possible. Used when assigning |value| +// to a field of another message, which means the message must be of a +// particular type. +// +// This will perform automatic conversions in some cases (for example, Time -> +// Google::Protobuf::Timestamp). If any new message is created, it will be +// created on |arena|, and any existing message will have its arena fused with +// |arena|. +const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, + const char* name, upb_Arena* arena); + +// Gets or constructs a Ruby wrapper object for the given message. The wrapper +// object will reference |arena| and ensure that it outlives this object. +VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m, + VALUE arena); + +// Gets the given field from this message. +VALUE Message_getfield(VALUE _self, const upb_FieldDef* f); + +// Implements #inspect for this message, printing the text to |b|. +void Message_PrintMessage(StringBuilder* b, const upb_Message* msg, + const upb_MessageDef* m); + +// Returns a hash value for the given message. +uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed); + +// Returns a deep copy of the given message. +upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, + upb_Arena* arena); + +// Checks that this Ruby object is a message, and raises an exception if not. +void Message_CheckClass(VALUE klass); + +// Returns a new Hash object containing the contents of this message. +VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info); + +// Creates a message class or enum module for this descriptor, respectively. +VALUE build_class_from_descriptor(VALUE descriptor); +VALUE build_module_from_enumdesc(VALUE _enumdesc); + +// Returns the Descriptor/EnumDescriptor for the given message class or enum +// module, respectively. Returns nil if this is not a message class or enum +// module. +VALUE MessageOrEnum_GetDescriptor(VALUE klass); + +// Decodes a Message from a byte sequence. +VALUE Message_decode_bytes(size_t size, const char* bytes, int options, + VALUE klass, bool freeze); + +// Recursively freeze message +VALUE Message_freeze(VALUE _self); + +// Call at startup to register all types in this module. +void Message_register(VALUE protobuf); + +#endif // RUBY_PROTOBUF_MESSAGE_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c new file mode 100755 index 0000000..6eea18c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.c @@ -0,0 +1,357 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "protobuf.h" + +#include "defs.h" +#include "map.h" +#include "message.h" +#include "repeated_field.h" + +VALUE cParseError; +VALUE cTypeError; + +const upb_FieldDef *map_field_key(const upb_FieldDef *field) { + const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field); + return upb_MessageDef_FindFieldByNumber(entry, 1); +} + +const upb_FieldDef *map_field_value(const upb_FieldDef *field) { + const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field); + return upb_MessageDef_FindFieldByNumber(entry, 2); +} + +// ----------------------------------------------------------------------------- +// StringBuilder, for inspect +// ----------------------------------------------------------------------------- + +struct StringBuilder { + size_t size; + size_t cap; + char *data; +}; + +typedef struct StringBuilder StringBuilder; + +static size_t StringBuilder_SizeOf(size_t cap) { + return sizeof(StringBuilder) + cap; +} + +StringBuilder *StringBuilder_New() { + const size_t cap = 128; + StringBuilder *builder = malloc(sizeof(*builder)); + builder->size = 0; + builder->cap = cap; + builder->data = malloc(builder->cap); + return builder; +} + +void StringBuilder_Free(StringBuilder *b) { + free(b->data); + free(b); +} + +void StringBuilder_Printf(StringBuilder *b, const char *fmt, ...) { + size_t have = b->cap - b->size; + size_t n; + va_list args; + + va_start(args, fmt); + n = vsnprintf(&b->data[b->size], have, fmt, args); + va_end(args); + + if (have <= n) { + while (have <= n) { + b->cap *= 2; + have = b->cap - b->size; + } + b->data = realloc(b->data, StringBuilder_SizeOf(b->cap)); + va_start(args, fmt); + n = vsnprintf(&b->data[b->size], have, fmt, args); + va_end(args); + PBRUBY_ASSERT(n < have); + } + + b->size += n; +} + +VALUE StringBuilder_ToRubyString(StringBuilder *b) { + VALUE ret = rb_str_new(b->data, b->size); + rb_enc_associate(ret, rb_utf8_encoding()); + return ret; +} + +static void StringBuilder_PrintEnum(StringBuilder *b, int32_t val, + const upb_EnumDef *e) { + const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber(e, val); + if (ev) { + StringBuilder_Printf(b, ":%s", upb_EnumValueDef_Name(ev)); + } else { + StringBuilder_Printf(b, "%" PRId32, val); + } +} + +void StringBuilder_PrintMsgval(StringBuilder *b, upb_MessageValue val, + TypeInfo info) { + switch (info.type) { + case kUpb_CType_Bool: + StringBuilder_Printf(b, "%s", val.bool_val ? "true" : "false"); + break; + case kUpb_CType_Float: { + VALUE str = rb_inspect(DBL2NUM(val.float_val)); + StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); + break; + } + case kUpb_CType_Double: { + VALUE str = rb_inspect(DBL2NUM(val.double_val)); + StringBuilder_Printf(b, "%s", RSTRING_PTR(str)); + break; + } + case kUpb_CType_Int32: + StringBuilder_Printf(b, "%" PRId32, val.int32_val); + break; + case kUpb_CType_UInt32: + StringBuilder_Printf(b, "%" PRIu32, val.uint32_val); + break; + case kUpb_CType_Int64: + StringBuilder_Printf(b, "%" PRId64, val.int64_val); + break; + case kUpb_CType_UInt64: + StringBuilder_Printf(b, "%" PRIu64, val.uint64_val); + break; + case kUpb_CType_String: + StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, + val.str_val.data); + break; + case kUpb_CType_Bytes: + StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size, + val.str_val.data); + break; + case kUpb_CType_Enum: + StringBuilder_PrintEnum(b, val.int32_val, info.def.enumdef); + break; + case kUpb_CType_Message: + Message_PrintMessage(b, val.msg_val, info.def.msgdef); + break; + } +} + +// ----------------------------------------------------------------------------- +// Arena +// ----------------------------------------------------------------------------- + +typedef struct { + upb_Arena *arena; + // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() + // macro to update VALUE references, as to trigger write barriers. + VALUE pinned_objs; +} Arena; + +static void Arena_mark(void *data) { + Arena *arena = data; + rb_gc_mark(arena->pinned_objs); +} + +static void Arena_free(void *data) { + Arena *arena = data; + upb_Arena_Free(arena->arena); + xfree(arena); +} + +static size_t Arena_memsize(const void *data) { + const Arena *arena = data; + size_t fused_count; + size_t memsize = upb_Arena_SpaceAllocated(arena->arena, &fused_count); + if (fused_count > 1) { + // If other arena were fused we attribute an equal + // share of memory usage to each one. + memsize /= fused_count; + } + return memsize + sizeof(Arena); +} + +static VALUE cArena; + +const rb_data_type_t Arena_type = { + "Google::Protobuf::Internal::Arena", + {Arena_mark, Arena_free, Arena_memsize}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static void *ruby_upb_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize, + size_t size, size_t *actual_size) { + if (size == 0) { + xfree(ptr); + return NULL; + } else { + return xrealloc(ptr, size); + } +} + +upb_alloc ruby_upb_alloc = {&ruby_upb_allocfunc}; + +static VALUE Arena_alloc(VALUE klass) { + Arena *arena = ALLOC(Arena); + arena->arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc); + arena->pinned_objs = Qnil; + return TypedData_Wrap_Struct(klass, &Arena_type, arena); +} + +upb_Arena *Arena_get(VALUE _arena) { + Arena *arena; + TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); + return arena->arena; +} + +void Arena_fuse(VALUE _arena, upb_Arena *other) { + Arena *arena; + TypedData_Get_Struct(_arena, Arena, &Arena_type, arena); + if (!upb_Arena_Fuse(arena->arena, other)) { + rb_raise(rb_eRuntimeError, + "Unable to fuse arenas. This should never happen since Ruby does " + "not use initial blocks"); + } +} + +VALUE Arena_new() { return Arena_alloc(cArena); } + +void Arena_register(VALUE module) { + VALUE internal = rb_define_module_under(module, "Internal"); + VALUE klass = rb_define_class_under(internal, "Arena", rb_cObject); + rb_define_alloc_func(klass, Arena_alloc); + rb_gc_register_address(&cArena); + cArena = klass; +} + +// ----------------------------------------------------------------------------- +// Object Cache +// ----------------------------------------------------------------------------- + +// Public ObjectCache API. + +VALUE weak_obj_cache = Qnil; +ID item_get; +ID item_try_add; + +static void ObjectCache_Init(VALUE protobuf) { + item_get = rb_intern("get"); + item_try_add = rb_intern("try_add"); + + rb_gc_register_address(&weak_obj_cache); + VALUE internal = rb_const_get(protobuf, rb_intern("Internal")); +#if SIZEOF_LONG >= SIZEOF_VALUE + VALUE cache_class = rb_const_get(internal, rb_intern("ObjectCache")); +#else + VALUE cache_class = rb_const_get(internal, rb_intern("LegacyObjectCache")); +#endif + + weak_obj_cache = rb_class_new_instance(0, NULL, cache_class); + rb_const_set(internal, rb_intern("OBJECT_CACHE"), weak_obj_cache); + rb_const_set(internal, rb_intern("SIZEOF_LONG"), INT2NUM(SIZEOF_LONG)); + rb_const_set(internal, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE)); +} + +static VALUE ObjectCache_GetKey(const void *key) { + VALUE key_val = (VALUE)key; + PBRUBY_ASSERT((key_val & 3) == 0); + // Ensure the key can be stored as a Fixnum since 1 bit is needed for + // FIXNUM_FLAG and 1 bit is needed for the sign bit. + VALUE new_key = LL2NUM(key_val >> 2); + PBRUBY_ASSERT(FIXNUM_P(new_key)); + return new_key; +} + +VALUE ObjectCache_TryAdd(const void *key, VALUE val) { + VALUE key_val = ObjectCache_GetKey(key); + return rb_funcall(weak_obj_cache, item_try_add, 2, key_val, val); +} + +// Returns the cached object for this key, if any. Otherwise returns Qnil. +VALUE ObjectCache_Get(const void *key) { + VALUE key_val = ObjectCache_GetKey(key); + return rb_funcall(weak_obj_cache, item_get, 1, key_val); +} + +/* + * call-seq: + * Google::Protobuf.discard_unknown(msg) + * + * Discard unknown fields in the given message object and recursively discard + * unknown fields in submessages. + */ +static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) { + const upb_MessageDef *m; + upb_Message *msg = Message_GetMutable(msg_rb, &m); + const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(m)); + if (!upb_Message_DiscardUnknown(msg, m, ext_pool, 128)) { + rb_raise(rb_eRuntimeError, "Messages nested too deeply."); + } + + return Qnil; +} + +/* + * call-seq: + * Google::Protobuf.deep_copy(obj) => copy_of_obj + * + * Performs a deep copy of a RepeatedField instance, a Map instance, or a + * message object, recursively copying its members. + */ +VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) { + VALUE klass = CLASS_OF(obj); + if (klass == cRepeatedField) { + return RepeatedField_deep_copy(obj); + } else if (klass == cMap) { + return Map_deep_copy(obj); + } else { + VALUE new_arena_rb = Arena_new(); + upb_Arena *new_arena = Arena_get(new_arena_rb); + const upb_MessageDef *m; + const upb_Message *msg = Message_Get(obj, &m); + upb_Message *new_msg = Message_deep_copy(msg, m, new_arena); + return Message_GetRubyWrapper(new_msg, m, new_arena_rb); + } +} + +// ----------------------------------------------------------------------------- +// Initialization/entry point. +// ----------------------------------------------------------------------------- + +// This must be named "Init_protobuf_c" because the Ruby module is named +// "protobuf_c" -- the VM looks for this symbol in our .so. +__attribute__((visibility("default"))) void Init_protobuf_c() { + VALUE google = rb_define_module("Google"); + VALUE protobuf = rb_define_module_under(google, "Protobuf"); + + ObjectCache_Init(protobuf); + Arena_register(protobuf); + Defs_register(protobuf); + RepeatedField_register(protobuf); + Map_register(protobuf); + Message_register(protobuf); + + cParseError = rb_const_get(protobuf, rb_intern("ParseError")); + rb_gc_register_mark_object(cParseError); + cTypeError = rb_const_get(protobuf, rb_intern("TypeError")); + rb_gc_register_mark_object(cTypeError); + + rb_define_singleton_method(protobuf, "discard_unknown", + Google_Protobuf_discard_unknown, 1); + rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy, + 1); +} + +// ----------------------------------------------------------------------------- +// Utilities +// ----------------------------------------------------------------------------- + +// Raises a Ruby error if val is frozen in Ruby or UPB. +void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen) { + if (RB_UNLIKELY(rb_obj_frozen_p(val)||upb_frozen)) { + rb_error_frozen_object(val); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h new file mode 100755 index 0000000..abb7c89 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/protobuf.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ +#define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ + +// Ruby 3+ defines NDEBUG itself, see: https://bugs.ruby-lang.org/issues/18777 +#ifdef NDEBUG +#include <ruby.h> +#else +#include <ruby.h> +#undef NDEBUG +#endif + +#include <assert.h> // Must be included after the NDEBUG logic above. +#include <ruby/encoding.h> +#include <ruby/vm.h> + +#include "defs.h" +#include "ruby-upb.h" + +// These operate on a map field (i.e., a repeated field of submessages whose +// submessage type is a map-entry msgdef). +const upb_FieldDef* map_field_key(const upb_FieldDef* field); +const upb_FieldDef* map_field_value(const upb_FieldDef* field); + +// ----------------------------------------------------------------------------- +// Arena +// ----------------------------------------------------------------------------- + +// A Ruby object that wraps an underlying upb_Arena. Any objects that are +// allocated from this arena should reference the Arena in rb_gc_mark(), to +// ensure that the object's underlying memory outlives any Ruby object that can +// reach it. + +VALUE Arena_new(); +upb_Arena* Arena_get(VALUE arena); + +// Fuses this arena to another, throwing a Ruby exception if this is not +// possible. +void Arena_fuse(VALUE arena, upb_Arena* other); + +// ----------------------------------------------------------------------------- +// ObjectCache +// ----------------------------------------------------------------------------- + +// Global object cache from upb array/map/message/symtab to wrapper object. +// +// This is a conceptually "weak" cache, in that it does not prevent "val" from +// being collected (though in Ruby <2.7 is it effectively strong, due to +// implementation limitations). + +// Tries to add a new entry to the cache, returning the newly installed value or +// the pre-existing entry. +VALUE ObjectCache_TryAdd(const void* key, VALUE val); + +// Returns the cached object for this key, if any. Otherwise returns Qnil. +VALUE ObjectCache_Get(const void* key); + +// ----------------------------------------------------------------------------- +// StringBuilder, for inspect +// ----------------------------------------------------------------------------- + +struct StringBuilder; +typedef struct StringBuilder StringBuilder; + +StringBuilder* StringBuilder_New(); +void StringBuilder_Free(StringBuilder* b); +void StringBuilder_Printf(StringBuilder* b, const char* fmt, ...); +VALUE StringBuilder_ToRubyString(StringBuilder* b); + +void StringBuilder_PrintMsgval(StringBuilder* b, upb_MessageValue val, + TypeInfo info); + +// ----------------------------------------------------------------------------- +// Utilities. +// ----------------------------------------------------------------------------- + +extern VALUE cTypeError; + +#ifdef NDEBUG +#define PBRUBY_ASSERT(expr) \ + do { \ + } while (false && (expr)) +#else +#define PBRUBY_ASSERT(expr) \ + if (!(expr)) \ + rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr) +#endif + +// Raises a Ruby error if val is frozen in Ruby or upb_frozen is true. +void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen); + +#define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c new file mode 100755 index 0000000..ed19346 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.c @@ -0,0 +1,728 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2014 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "repeated_field.h" + +#include "convert.h" +#include "defs.h" +#include "message.h" +#include "protobuf.h" + +// ----------------------------------------------------------------------------- +// Repeated field container type. +// ----------------------------------------------------------------------------- + +typedef struct { + const upb_Array* array; // Can get as mutable when non-frozen. + TypeInfo type_info; + VALUE type_class; // To GC-root the msgdef/enumdef in type_info. + VALUE arena; // To GC-root the upb_Array. +} RepeatedField; + +VALUE cRepeatedField; + +static void RepeatedField_mark(void* _self) { + RepeatedField* self = (RepeatedField*)_self; + rb_gc_mark(self->type_class); + rb_gc_mark(self->arena); +} + +const rb_data_type_t RepeatedField_type = { + "Google::Protobuf::RepeatedField", + {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL}, + .flags = RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static RepeatedField* ruby_to_RepeatedField(VALUE _self) { + RepeatedField* self; + TypedData_Get_Struct(_self, RepeatedField, &RepeatedField_type, self); + return self; +} + +static upb_Array* RepeatedField_GetMutable(VALUE _self) { + const upb_Array* array = ruby_to_RepeatedField(_self)->array; + Protobuf_CheckNotFrozen(_self, upb_Array_IsFrozen(array)); + return (upb_Array*)array; +} + +VALUE RepeatedField_alloc(VALUE klass) { + RepeatedField* self = ALLOC(RepeatedField); + self->arena = Qnil; + self->type_class = Qnil; + self->array = NULL; + return TypedData_Wrap_Struct(klass, &RepeatedField_type, self); +} + +VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f) { + PBRUBY_ASSERT(upb_FieldDef_IsRepeated(f)); + VALUE val = ObjectCache_Get(f); + + if (val == Qnil) { + val = RepeatedField_alloc(cRepeatedField); + RepeatedField* self; + TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self); + self->arena = Arena_new(); + TypeInfo type_info = TypeInfo_get(f); + self->array = upb_Array_New(Arena_get(self->arena), type_info.type); + self->type_info = type_info; + if (self->type_info.type == kUpb_CType_Message) { + self->type_class = Descriptor_DefToClass(type_info.def.msgdef); + } + val = ObjectCache_TryAdd(f, RepeatedField_freeze(val)); + } + PBRUBY_ASSERT(RB_OBJ_FROZEN(val)); + PBRUBY_ASSERT(upb_Array_IsFrozen(ruby_to_RepeatedField(val)->array)); + return val; +} + +VALUE RepeatedField_GetRubyWrapper(const upb_Array* array, TypeInfo type_info, + VALUE arena) { + PBRUBY_ASSERT(array); + PBRUBY_ASSERT(arena != Qnil); + VALUE val = ObjectCache_Get(array); + + if (val == Qnil) { + val = RepeatedField_alloc(cRepeatedField); + RepeatedField* self; + TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self); + self->array = array; + self->arena = arena; + self->type_info = type_info; + if (self->type_info.type == kUpb_CType_Message) { + self->type_class = Descriptor_DefToClass(type_info.def.msgdef); + } + val = ObjectCache_TryAdd(array, val); + } + + PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type); + PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef == + type_info.def.msgdef); + PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array); + return val; +} + +static VALUE RepeatedField_new_this_type(RepeatedField* from) { + VALUE arena_rb = Arena_new(); + upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type); + VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb); + PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class); + return ret; +} + +void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array, + TypeInfo info) { + bool first = true; + StringBuilder_Printf(b, "["); + size_t n = array ? upb_Array_Size(array) : 0; + for (size_t i = 0; i < n; i++) { + if (first) { + first = false; + } else { + StringBuilder_Printf(b, ", "); + } + StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info); + } + StringBuilder_Printf(b, "]"); +} + +VALUE RepeatedField_deep_copy(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + VALUE new_rptfield = RepeatedField_new_this_type(self); + RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield); + VALUE arena_rb = new_self->arena; + upb_Array* new_array = RepeatedField_GetMutable(new_rptfield); + upb_Arena* arena = Arena_get(arena_rb); + size_t elements = upb_Array_Size(self->array); + + upb_Array_Resize(new_array, elements, arena); + + size_t size = upb_Array_Size(self->array); + for (size_t i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena); + upb_Array_Set(new_array, i, copy); + } + + return new_rptfield; +} + +const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field, + upb_Arena* arena) { + RepeatedField* self; + TypeInfo type_info = TypeInfo_get(field); + + if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) || + RTYPEDDATA_TYPE(val) != &RepeatedField_type) { + rb_raise(cTypeError, "Expected repeated field array"); + } + + self = ruby_to_RepeatedField(val); + if (self->type_info.type != type_info.type) { + rb_raise(cTypeError, "Repeated field array has wrong element type"); + } + + if (self->type_info.def.msgdef != type_info.def.msgdef) { + rb_raise(cTypeError, "Repeated field array has wrong message/enum class"); + } + + Arena_fuse(self->arena, arena); + return self->array; +} + +static int index_position(VALUE _index, RepeatedField* repeated_field) { + int index = NUM2INT(_index); + if (index < 0) index += upb_Array_Size(repeated_field->array); + return index; +} + +static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) { + size_t size = upb_Array_Size(self->array); + VALUE ary = rb_ary_new2(size); + long i; + + for (i = beg; i < beg + len; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena); + rb_ary_push(ary, elem); + } + return ary; +} + +/** + * ruby-doc: RepeatedField + * + */ + +/* + * ruby-doc: RepeatedField#each + * + * Invokes the block once for each element of the repeated field. RepeatedField + * also includes Enumerable; combined with this method, the repeated field thus + * acts like an ordinary Ruby sequence. + * + * @yield [Object] + * @return [self] + */ +static VALUE RepeatedField_each(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + int size = upb_Array_Size(self->array); + int i; + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); + rb_yield(val); + } + return _self; +} + +/* + * ruby-doc: RepeatedField#[] + * + * Accesses the element at the given index. Returns nil on out-of-bounds + * + * @param index [Integer] + * @return [Object,nil] + */ +static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + long size = upb_Array_Size(self->array); + + VALUE arg = argv[0]; + long beg, len; + + if (argc == 1) { + if (FIXNUM_P(arg)) { + /* standard case */ + upb_MessageValue msgval; + int index = index_position(argv[0], self); + if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) { + return Qnil; + } + msgval = upb_Array_Get(self->array, index); + return Convert_UpbToRuby(msgval, self->type_info, self->arena); + } else { + /* check if idx is Range */ + switch (rb_range_beg_len(arg, &beg, &len, size, 0)) { + case Qfalse: + break; + case Qnil: + return Qnil; + default: + return RepeatedField_subarray(self, beg, len); + } + } + } + + /* assume 2 arguments */ + beg = NUM2LONG(argv[0]); + len = NUM2LONG(argv[1]); + if (beg < 0) { + beg += size; + } + if (beg >= size) { + return Qnil; + } + return RepeatedField_subarray(self, beg, len); +} + +/* + * ruby-doc: RepeatedField#[]= + * + * Sets the element at the given index. On out-of-bounds assignments, extends + * the array and fills the hole (if any) with default values. + * + * @param index [Integer] + * @param value [Object + * @return [nil] + */ +static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { + RepeatedField* self = ruby_to_RepeatedField(_self); + int size = upb_Array_Size(self->array); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); + + int index = index_position(_index, self); + if (index < 0 || index >= (INT_MAX - 1)) { + return Qnil; + } + + if (index >= size) { + upb_Array_Resize(array, index + 1, arena); + upb_MessageValue fill; + memset(&fill, 0, sizeof(fill)); + for (int i = size; i < index; i++) { + // Fill default values. + // TODO: should this happen at the upb level? + upb_Array_Set(array, i, fill); + } + } + + upb_Array_Set(array, index, msgval); + return Qnil; +} + +/* + * ruby-doc: RepeatedField#push + * + * Adds a new element to the repeated field. + * + * @param value [Object] + * @return [self] + */ +static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_Array* array = RepeatedField_GetMutable(_self); + int i; + + for (i = 0; i < argc; i++) { + upb_MessageValue msgval = + Convert_RubyToUpb(argv[i], "", self->type_info, arena); + upb_Array_Append(array, msgval, arena); + } + + return _self; +} + +/* + * ruby-doc: RepeatedField#<< + * + * Adds a new element to the repeated field. + * + * @param value [Object] + * @return [self] + */ +static VALUE RepeatedField_push(VALUE _self, VALUE val) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Arena* arena = Arena_get(self->arena); + upb_Array* array = RepeatedField_GetMutable(_self); + + upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); + upb_Array_Append(array, msgval, arena); + + return _self; +} + +/* + * Private ruby method, used by RepeatedField.pop + */ +static VALUE RepeatedField_pop_one(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + size_t size = upb_Array_Size(self->array); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_MessageValue last; + VALUE ret; + + if (size == 0) { + return Qnil; + } + + last = upb_Array_Get(self->array, size - 1); + ret = Convert_UpbToRuby(last, self->type_info, self->arena); + + upb_Array_Resize(array, size - 1, Arena_get(self->arena)); + return ret; +} + +/* + * ruby-doc: RepeatedField#replace + * + * Replaces the contents of the repeated field with the given list of elements. + * + * @param list [Array] + * @return [Array] + */ +static VALUE RepeatedField_replace(VALUE _self, VALUE list) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Array* array = RepeatedField_GetMutable(_self); + int i; + + Check_Type(list, T_ARRAY); + upb_Array_Resize(array, 0, Arena_get(self->arena)); + + for (i = 0; i < RARRAY_LEN(list); i++) { + RepeatedField_push(_self, rb_ary_entry(list, i)); + } + + return list; +} + +/* + * ruby-doc: RepeatedField#clear + * + * Clears (removes all elements from) this repeated field. + * + * @return [self] + */ +static VALUE RepeatedField_clear(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Array* array = RepeatedField_GetMutable(_self); + upb_Array_Resize(array, 0, Arena_get(self->arena)); + return _self; +} + +/* + * ruby-doc: RepeatedField#length + * + * Returns the length of this repeated field. + * + * @return [Integer] + */ +static VALUE RepeatedField_length(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + return INT2NUM(upb_Array_Size(self->array)); +} + +/* + * ruby-doc: RepeatedField#dup + * + * Duplicates this repeated field with a shallow copy. References to all + * non-primitive element objects (e.g., submessages) are shared. + * + * @return [RepeatedField] + */ +static VALUE RepeatedField_dup(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + VALUE new_rptfield = RepeatedField_new_this_type(self); + RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield); + upb_Array* new_array = RepeatedField_GetMutable(new_rptfield); + upb_Arena* arena = Arena_get(new_rptfield_self->arena); + int size = upb_Array_Size(self->array); + int i; + + Arena_fuse(self->arena, arena); + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + upb_Array_Append(new_array, msgval, arena); + } + + return new_rptfield; +} + +/* + * ruby-doc: RepeatedField#to_ary + * + * Used when converted implicitly into array, e.g. compared to an Array. + * Also called as a fallback of Object#to_a + * + * @return [Array] + */ +VALUE RepeatedField_to_ary(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + int size = upb_Array_Size(self->array); + VALUE ary = rb_ary_new2(size); + int i; + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); + rb_ary_push(ary, val); + } + + return ary; +} + +/* + * ruby-doc: RepeatedField#== + * + * Compares this repeated field to another. Repeated fields are equal if their + * element types are equal, their lengths are equal, and each element is equal. + * Elements are compared as per normal Ruby semantics, by calling their :== + * methods (or performing a more efficient comparison for primitive types). + * + * Repeated fields with dissimilar element types are never equal, even if value + * comparison (for example, between integers and floats) would have otherwise + * indicated that every element has equal value. + * + * @param other [RepeatedField] + * @return [Boolean] + */ +VALUE RepeatedField_eq(VALUE _self, VALUE _other) { + RepeatedField* self; + RepeatedField* other; + + if (_self == _other) { + return Qtrue; + } + + if (TYPE(_other) == T_ARRAY) { + VALUE self_ary = RepeatedField_to_ary(_self); + return rb_equal(self_ary, _other); + } + + self = ruby_to_RepeatedField(_self); + other = ruby_to_RepeatedField(_other); + size_t n = upb_Array_Size(self->array); + + if (self->type_info.type != other->type_info.type || + self->type_class != other->type_class || + upb_Array_Size(other->array) != n) { + return Qfalse; + } + + for (size_t i = 0; i < n; i++) { + upb_MessageValue val1 = upb_Array_Get(self->array, i); + upb_MessageValue val2 = upb_Array_Get(other->array, i); + if (!Msgval_IsEqual(val1, val2, self->type_info)) { + return Qfalse; + } + } + + return Qtrue; +} + +/* + * ruby-doc: RepeatedField#frozen? + * + * Returns true if the repeated field is frozen in either Ruby or the underlying + * representation. Freezes the Ruby repeated field object if it is not already + * frozen in Ruby but it is frozen in the underlying representation. + * + * @return [Boolean] + */ +VALUE RepeatedField_frozen(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + if (!upb_Array_IsFrozen(self->array)) { + PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self)); + return Qfalse; + } + + // Lazily freeze the Ruby wrapper. + if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self); + return Qtrue; +} + +/* + * ruby-doc: RepeatedField#freeze + * + * Freezes the repeated field object. We have to intercept this so we can freeze + * the underlying representation, not just the Ruby wrapper. + * + * @return [self] + */ +VALUE RepeatedField_freeze(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + if (RB_OBJ_FROZEN(_self)) { + PBRUBY_ASSERT(upb_Array_IsFrozen(self->array)); + return _self; + } + + if (!upb_Array_IsFrozen(self->array)) { + if (self->type_info.type == kUpb_CType_Message) { + upb_Array_Freeze(RepeatedField_GetMutable(_self), + upb_MessageDef_MiniTable(self->type_info.def.msgdef)); + } else { + upb_Array_Freeze(RepeatedField_GetMutable(_self), NULL); + } + } + RB_OBJ_FREEZE(_self); + return _self; +} + +/* + * ruby-doc: RepeatedField#hash + * + * Returns a hash value computed from this repeated field's elements. + * + * @return [Integer] + */ +VALUE RepeatedField_hash(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + uint64_t hash = 0; + size_t n = upb_Array_Size(self->array); + + for (size_t i = 0; i < n; i++) { + upb_MessageValue val = upb_Array_Get(self->array, i); + hash = Msgval_GetHash(val, self->type_info, hash); + } + + return LL2NUM(hash); +} + +/* + * ruby-doc: RepeatedField#+ + * + * Returns a new repeated field that contains the concatenated list of this + * repeated field's elements and other's elements. The other (second) list may + * be either another repeated field or a Ruby array. + * + * @param other [Array,RepeatedField] + * @return [RepeatedField] + */ +VALUE RepeatedField_plus(VALUE _self, VALUE list) { + VALUE dupped_ = RepeatedField_dup(_self); + + if (TYPE(list) == T_ARRAY) { + int i; + for (i = 0; i < RARRAY_LEN(list); i++) { + VALUE elem = rb_ary_entry(list, i); + RepeatedField_push(dupped_, elem); + } + } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) && + RTYPEDDATA_TYPE(list) == &RepeatedField_type) { + RepeatedField* self = ruby_to_RepeatedField(_self); + RepeatedField* list_rptfield = ruby_to_RepeatedField(list); + RepeatedField* dupped = ruby_to_RepeatedField(dupped_); + upb_Array* dupped_array = RepeatedField_GetMutable(dupped_); + upb_Arena* arena = Arena_get(dupped->arena); + Arena_fuse(list_rptfield->arena, arena); + int size = upb_Array_Size(list_rptfield->array); + int i; + + if (self->type_info.type != list_rptfield->type_info.type || + self->type_class != list_rptfield->type_class) { + rb_raise(rb_eArgError, + "Attempt to append RepeatedField with different element type."); + } + + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i); + upb_Array_Append(dupped_array, msgval, arena); + } + } else { + rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); + } + + return dupped_; +} + +/* + * ruby-doc: RepeatedField#concat + * + * concats the passed in array to self. Returns a Ruby array. + * + * @param other [RepeatedField] + * @return [Array] + */ +VALUE RepeatedField_concat(VALUE _self, VALUE list) { + int i; + + Check_Type(list, T_ARRAY); + for (i = 0; i < RARRAY_LEN(list); i++) { + RepeatedField_push(_self, rb_ary_entry(list, i)); + } + return _self; +} + +/* + * ruby-doc: RepeatedField#initialize + * + * Creates a new repeated field. The provided type must be a Ruby symbol, and + * can take on the same values as those accepted by {FieldDescriptor#type=}. If + * the type is :message or :enum, type_class must be non-nil, and must be the + * Ruby class or module returned by {Descriptor#msgclass} or + * {EnumDescriptor#enummodule}, respectively. An initial list of elements may + * also be provided. + * + * @param type [Symbol] + * @param type_class [Class<AbstractMessage>, Module] + * @paramdefault type_class nil + * @param initial_elems [Array] + * @paramdefault initial_elems [] + * @return [RepeatedField] + */ +VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + upb_Arena* arena; + VALUE ary = Qnil; + + self->arena = Arena_new(); + arena = Arena_get(self->arena); + + if (argc < 1) { + rb_raise(rb_eArgError, "Expected at least 1 argument."); + } + + self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary); + self->array = upb_Array_New(arena, self->type_info.type); + VALUE stored_val = ObjectCache_TryAdd(self->array, _self); + PBRUBY_ASSERT(stored_val == _self); + + if (ary != Qnil) { + if (!RB_TYPE_P(ary, T_ARRAY)) { + rb_raise(rb_eArgError, "Expected array as initialize argument"); + } + for (int i = 0; i < RARRAY_LEN(ary); i++) { + RepeatedField_push(_self, rb_ary_entry(ary, i)); + } + } + return Qnil; +} + +void RepeatedField_register(VALUE module) { + VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject); + rb_define_alloc_func(klass, RepeatedField_alloc); + rb_gc_register_address(&cRepeatedField); + cRepeatedField = klass; + + rb_define_method(klass, "initialize", RepeatedField_init, -1); + rb_define_method(klass, "each", RepeatedField_each, 0); + rb_define_method(klass, "[]", RepeatedField_index, -1); + rb_define_method(klass, "at", RepeatedField_index, -1); + rb_define_method(klass, "[]=", RepeatedField_index_set, 2); + rb_define_method(klass, "push", RepeatedField_push_vararg, -1); + rb_define_method(klass, "<<", RepeatedField_push, 1); + rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0); + rb_define_method(klass, "replace", RepeatedField_replace, 1); + rb_define_method(klass, "clear", RepeatedField_clear, 0); + rb_define_method(klass, "length", RepeatedField_length, 0); + rb_define_method(klass, "size", RepeatedField_length, 0); + rb_define_method(klass, "dup", RepeatedField_dup, 0); + // Also define #clone so that we don't inherit Object#clone. + rb_define_method(klass, "clone", RepeatedField_dup, 0); + rb_define_method(klass, "==", RepeatedField_eq, 1); + rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0); + rb_define_method(klass, "freeze", RepeatedField_freeze, 0); + rb_define_method(klass, "frozen?", RepeatedField_frozen, 0); + rb_define_method(klass, "hash", RepeatedField_hash, 0); + rb_define_method(klass, "+", RepeatedField_plus, 1); + rb_define_method(klass, "concat", RepeatedField_concat, 1); + rb_include_module(klass, rb_mEnumerable); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h new file mode 100755 index 0000000..1ae31cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/repeated_field.h @@ -0,0 +1,45 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef RUBY_PROTOBUF_REPEATED_FIELD_H_ +#define RUBY_PROTOBUF_REPEATED_FIELD_H_ + +#include "protobuf.h" +#include "ruby-upb.h" + +// Returns a frozen sentinel Ruby wrapper object for an empty upb_Array of the +// type specified by the field. Creates one if it doesn't exist. +VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f); + +// Returns a Ruby wrapper object for the given upb_Array, which will be created +// if one does not exist already. +VALUE RepeatedField_GetRubyWrapper(const upb_Array* msg, TypeInfo type_info, + VALUE arena); + +// Gets the underlying upb_Array for this Ruby RepeatedField object, which must +// have a type that matches |f|. If this is not a repeated field or the type +// doesn't match, raises an exception. +const upb_Array* RepeatedField_GetUpbArray(VALUE value, const upb_FieldDef* f, + upb_Arena* arena); + +// Implements #inspect for this repeated field by appending its contents to |b|. +void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array, + TypeInfo info); + +// Returns a deep copy of this RepeatedField object. +VALUE RepeatedField_deep_copy(VALUE obj); + +// Ruby class of Google::Protobuf::RepeatedField. +extern VALUE cRepeatedField; + +// Call at startup to register all types in this module. +void RepeatedField_register(VALUE module); + +// Recursively freeze RepeatedField. +VALUE RepeatedField_freeze(VALUE _self); + +#endif // RUBY_PROTOBUF_REPEATED_FIELD_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c new file mode 100755 index 0000000..841c0f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.c @@ -0,0 +1,18154 @@ +/* Amalgamated source file */ +#include "ruby-upb.h" + +/* + * This is where we define internal portability macros used across upb. + * + * All of these macros are undef'd in undef.inc to avoid leaking them to users. + * + * The correct usage is: + * + * #include "upb/foobar.h" + * #include "upb/baz.h" + * + * // MUST be last included header. + * #include "upb/port/def.inc" + * + * // Code for this file. + * // <...> + * + * // Can be omitted for .c files, required for .h. + * #include "upb/port/undef.inc" + * + * This file is private and must not be included by users! + */ + +#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +#error upb requires C99 or C++17 or MSVC >= 2015. +#endif + +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +#define UPB_GNUC_MIN(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +#define UPB_GNUC_MIN(x, y) 0 +#endif + +// Macros for checking for compiler attributes, defined here to avoid the +// problem described in +// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. +#ifdef __has_attribute +#define UPB_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define UPB_HAS_ATTRIBUTE(x) 0 +#endif + +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define UPB_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define UPB_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +// Once in a while we want to use this macro in a C++-only portion of an +// otherwise C-compatible header, so we copy and paste this from ABSL. +#if UPB_HAS_CPP_ATTRIBUTE(deprecated) && UPB_HAS_CPP_ATTRIBUTE(clang::annotate) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]] +#elif UPB_HAS_CPP_ATTRIBUTE(deprecated) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated]] +#else +#define UPB_DEPRECATE_AND_INLINE() +#endif + +#ifdef __has_builtin +#define UPB_HAS_BUILTIN(x) __has_builtin(x) +#else +#define UPB_HAS_BUILTIN(x) 0 +#endif + +#ifdef __has_extension +#define UPB_HAS_EXTENSION(x) __has_extension(x) +#else +#define UPB_HAS_EXTENSION(x) 0 +#endif + +#ifdef __has_feature +#define UPB_HAS_FEATURE(x) __has_feature(x) +#else +#define UPB_HAS_FEATURE(x) 0 +#endif + +#include <assert.h> +#include <setjmp.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef UINTPTR_MAX +Error, UINTPTR_MAX is undefined +#endif + +#if UINTPTR_MAX == 0xffffffff +#define UPB_SIZE(size32, size64) size32 +#else +#define UPB_SIZE(size32, size64) size64 +#endif + +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) + +// A flexible array member may have lower alignment requirements than the struct +// overall - in that case, it can overlap with the trailing padding of the rest +// of the struct, and a naive sizeof(base) + sizeof(flex) * count calculation +// will not take into account that overlap, and allocate more than is required. +#define UPB_SIZEOF_FLEX(type, member, count) \ + UPB_MAX(sizeof(type), offsetof(type, member[count])) + +#define UPB_SIZEOF_FLEX_WOULD_OVERFLOW(type, member, count) \ + (((SIZE_MAX - offsetof(type, member[0])) / \ + (offsetof(type, member[1]) - offsetof(type, member[0]))) < (size_t)count) + +#define UPB_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +#define UPB_MAPTYPE_STRING 0 + +// UPB_EXPORT: always generate a public symbol. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_EXPORT __attribute__((visibility("default"))) __attribute__((used)) +#else +#define UPB_EXPORT +#endif + +// UPB_INLINE: inline if possible, emit standalone code if required. +#ifdef __cplusplus +#define UPB_INLINE inline +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_INLINE static __inline__ +#else +#define UPB_INLINE static +#endif + +// UPB_INLINE_IF_NOT_GCC: because gcc can be very noisy at times. +#if defined(__GNUC__) && !defined(__clang__) +#define UPB_INLINE_IF_NOT_GCC static +#else +#define UPB_INLINE_IF_NOT_GCC UPB_INLINE +#endif + +#ifdef UPB_BUILD_API +#define UPB_API UPB_EXPORT +#define UPB_API_INLINE UPB_EXPORT +#else +#define UPB_API +#define UPB_API_INLINE UPB_INLINE +#endif + +#ifdef EXPORT_UPBC +#define UPBC_API UPB_EXPORT +#else +#define UPBC_API +#endif + +#if UPB_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#else +#define UPB_ASAN 0 +#endif + +#if UPB_HAS_FEATURE(hwaddress_sanitizer) +#define UPB_HWASAN 1 +#define UPB_HWASAN_POISON_TAG 17 +#define UPB_MALLOC_ALIGN 16 +#else +#define UPB_HWASAN 0 +#define UPB_MALLOC_ALIGN 8 +#endif + +#if UPB_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) +#define UPB_TSAN 1 +#else +#define UPB_TSAN 0 +#endif + +#if UPB_HAS_FEATURE(memory_sanitizer) +#define UPB_MSAN 1 +#else +#define UPB_MSAN 0 +#endif + +// An unfortunate concession to C++17 and MSVC, which don't support zero-sized +// structs. +#if UPB_ASAN || UPB_HWASAN || UPB_TSAN +#define UPB_XSAN_MEMBER upb_Xsan xsan; +#define UPB_XSAN(st) (&(st)->xsan) +#define UPB_XSAN_STRUCT_SIZE 1 +#else +#define UPB_XSAN_MEMBER +#define UPB_XSAN(st) (NULL) +#define UPB_XSAN_STRUCT_SIZE 0 +#endif + +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN) + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_alignof) || \ + defined(__cplusplus) +#define UPB_ALIGN_OF(type) alignof(type) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_alignof) +#define UPB_ALIGN_OF(type) _Alignof(type) +#elif UPB_GNUC_MIN(2, 95) +#define UPB_ALIGN_OF(type) __alignof__(type) +#elif defined(_MSC_VER) +#define UPB_ALIGN_OF(type) __alignof(type) +#else +#define UPB_ALIGN_OF(type) \ + offsetof( \ + struct { \ + char c; \ + type member; \ + }, \ + member) +#endif + +#ifdef _MSC_VER +// Some versions of our Windows compiler don't support the C11 syntax. +#define UPB_ALIGN_AS(x) __declspec(align(x)) +#elif defined(__GNUC__) +#define UPB_ALIGN_AS(x) __attribute__((aligned(x))) +#else +#define UPB_ALIGN_AS(x) _Alignas(x) +#endif + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_static_assert) || \ + defined(__cplusplus) +#define UPB_STATIC_ASSERT(val, msg) static_assert((val), msg) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_static_assert) || \ + UPB_GNUC_MIN(4, 6) +#define UPB_STATIC_ASSERT(val, msg) _Static_assert((val), msg) +#else +// Unfortunately this hack doesn't work inside struct declarations, but it works +// everywhere else +#define UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) s1##s2 +#define UPB_STATIC_ASSERT_CONCAT(s1, s2) UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) +#ifdef __COUNTER__ +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __COUNTER__)[(condition) ? 1 : -1] +#else +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __LINE__)[(condition) ? 1 : -1] +#endif +#endif + +// Hints to the compiler about likely/unlikely branches. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_LIKELY(x) __builtin_expect((bool)(x), 1) +#define UPB_UNLIKELY(x) __builtin_expect((bool)(x), 0) +#else +#define UPB_LIKELY(x) (x) +#define UPB_UNLIKELY(x) (x) +#endif + +#if UPB_HAS_BUILTIN(__builtin_expect_with_probability) +#define UPB_UNPREDICTABLE(x) \ + __builtin_expect_with_probability((bool)(x), 1, 0.5) +#else +#define UPB_UNPREDICTABLE(x) (x) +#endif + +// Macros for function attributes on compilers that support them. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) static +#define UPB_NOINLINE __attribute__((noinline)) +#define UPB_NORETURN __attribute__((__noreturn__)) +#define UPB_PRINTF(str, first_vararg) \ + __attribute__((format(printf, str, first_vararg))) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE static +#define UPB_NORETURN __declspec(noreturn) +#define UPB_PRINTF(str, first_vararg) +#else /* !defined(__GNUC__) */ +#define UPB_FORCEINLINE static +#define UPB_NOINLINE +#define UPB_NORETURN +#define UPB_PRINTF(str, first_vararg) +#endif + +#if defined(__clang__) +#define UPB_NODEREF __attribute__((noderef)) +#else +#define UPB_NODEREF +#endif + +#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define UPB_UNUSED(var) (void)(var) + +// UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) \ + if (!(expr)) __builtin_unreachable() +#elif defined _MSC_VER +#define UPB_ASSUME(expr) \ + if (!(expr)) __assume(0) +#else +#define UPB_ASSUME(expr) \ + do { \ + } while (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + +#if UPB_HAS_BUILTIN(__builtin_constant_p) && UPB_HAS_ATTRIBUTE(const) +#define UPB_MAYBE_ASSUME(pred, x) \ + if (__builtin_constant_p(pred) && pred) UPB_ASSUME(x) +#define UPB_ATTR_CONST __attribute__((const)) +#else +#define UPB_MAYBE_ASSUME(pred, x) +#define UPB_ATTR_CONST +#endif + +/* UPB_ASSERT(): in release mode, we use the expression without letting it be + * evaluated. This prevents "unused variable" warnings. */ +#ifdef NDEBUG +#define UPB_ASSERT(expr) \ + do { \ + } while (false && (expr)) +#else +#define UPB_ASSERT(expr) assert(expr) +#endif + +#if !defined(NDEBUG) && !defined(UPB_TSAN) +#define UPB_ENABLE_REF_CYCLE_CHECKS 1 +#else +#define UPB_ENABLE_REF_CYCLE_CHECKS 0 +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __assume(0); \ + } while (0) +#else +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + } while (0) +#endif + +#ifdef __ANDROID__ +#define UPB_DEFAULT_MAX_BLOCK_SIZE 8192 +#else +#define UPB_DEFAULT_MAX_BLOCK_SIZE 32768 +#endif + +/* UPB_SETJMP() / UPB_LONGJMP() */ +// Android uses a custom libc that does not implement all of posix, but it has +// had sigsetjmp/siglongjmp forever on arm and since API 12 on x86. Apple has +// sigsetjmp, but does not define the posix feature test macro. +#if defined(__APPLE__) || defined(_POSIX_C_SOURCE) || defined(__ANDROID__) +// avoid setting/restoring signal mask, which involves costly syscalls +#define UPB_SETJMP(buf) sigsetjmp(buf, 0) +#define UPB_LONGJMP(buf, val) siglongjmp(buf, val) +#elif defined(WASM_WAMR) +#define UPB_SETJMP(buf) 0 +#define UPB_LONGJMP(buf, val) abort() +#else +#define UPB_SETJMP(buf) setjmp(buf) +#define UPB_LONGJMP(buf, val) longjmp(buf, val) +#endif + +#if ((__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)) || \ + UPB_HAS_EXTENSION(c_atomic) || \ + defined(__GNUC__) // GCC supported atomics as an extension before it + // supported __has_extension +#define UPB_USE_C11_ATOMICS +#elif defined(_MSC_VER) +#define UPB_USE_MSC_ATOMICS +#endif + +#if defined(UPB_USE_C11_ATOMICS) +#define UPB_ATOMIC(T) _Atomic(T) +#elif defined(UPB_USE_MSC_ATOMICS) +#define UPB_ATOMIC(T) volatile T +#else +#define UPB_ATOMIC(T) T +#endif + +/* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */ +#define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr)) + +#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only + +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + +/* Configure whether fasttable is switched on or not. *************************/ + +#if UPB_HAS_ATTRIBUTE(musttail) +#define UPB_MUSTTAIL __attribute__((musttail)) +#else +#define UPB_MUSTTAIL +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_most) && !defined(__i386__) +#define UPB_PRESERVE_MOST __attribute__((preserve_most)) +#else +#define UPB_PRESERVE_MOST +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_none) +#define UPB_PRESERVE_NONE __attribute__((preserve_none)) +#else +#define UPB_PRESERVE_NONE +#endif + +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +#define UPB_ARM64_ASM 1 +#else +#define UPB_ARM64_ASM 0 +#endif + +/* When compiling with branch protection, we need to ensure that all branch + * targets in assembly use the appropriate landing pad instruction. These + * instructions are backwards compatible with processors that don't have + * FEAT_BTI and are treated as nops. + */ +#if UPB_ARM64_ASM && defined(__ARM_FEATURE_BTI_DEFAULT) +#if __ARM_FEATURE_BTI_DEFAULT == 1 +#define UPB_ARM64_BTI_DEFAULT 1 +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif + +/* This check is not fully robust: it does not require that we have "musttail" + * support available. We need tail calls to avoid consuming arbitrary amounts + * of stack space. + * + * GCC/Clang can mostly be trusted to generate tail calls as long as + * optimization is enabled, but, debug builds will not generate tail calls + * unless "musttail" is available. + * + * We should probably either: + * 1. require that the compiler supports musttail. + * 2. add some fallback code for when musttail isn't available (ie. return + * instead of tail calling). This is safe and portable, but this comes at + * a CPU cost. + */ +#if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) +#define UPB_FASTTABLE_SUPPORTED 1 +#else +#define UPB_FASTTABLE_SUPPORTED 0 +#endif + +/* define UPB_ENABLE_FASTTABLE to force fast table support. + * This is useful when we want to ensure we are really getting fasttable, + * for example for testing or benchmarking. */ +#if defined(UPB_ENABLE_FASTTABLE) +#if !UPB_FASTTABLE_SUPPORTED +#error fasttable is x86-64/ARM64 only and requires GCC or Clang. +#endif +#define UPB_FASTTABLE 1 +/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible. + * This is useful for releasing code that might be used on multiple platforms, + * for example the PHP or Ruby C extensions. */ +#elif defined(UPB_TRY_ENABLE_FASTTABLE) +#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#else +#define UPB_FASTTABLE 0 +#endif + +/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully + * degrade to non-fasttable if the runtime or platform do not support it. */ +#if !UPB_FASTTABLE +#define UPB_FASTTABLE_INIT(...) +#define UPB_FASTTABLE_MASK(mask) -1 +#else +#define UPB_FASTTABLE_INIT(...) __VA_ARGS__ +#define UPB_FASTTABLE_MASK(mask) mask +#endif + +#undef UPB_FASTTABLE_SUPPORTED + +#if defined(__cplusplus) +#if defined(__clang__) || UPB_GNUC_MIN(6, 0) +// https://gcc.gnu.org/gcc-6/changes.html +#define UPB_DEPRECATED [[deprecated]] +#else +#define UPB_DEPRECATED +#endif +#else +#define UPB_DEPRECATED +#endif + +#if defined(UPB_IS_GOOGLE3) && \ + (!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0) +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_IS_GOOGLE3) && defined(UPB_BOOTSTRAP_STAGE) && \ + UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) proto2__##sym##_msg_init() +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() +#else +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init +#endif + +#undef UPB_IS_GOOGLE3 + +#ifdef __clang__ +#define UPB_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address"))) +#else +#define UPB_NO_SANITIZE_ADDRESS +#endif + +#if defined(__GNUC__) && (defined(__clang__) || UPB_GNUC_MIN(11, 0)) +#define UPB_RETAIN __attribute__((retain)) +#else +#define UPB_RETAIN +#endif + +// Linker arrays combine elements from multiple translation units into a single +// array that can be iterated over at runtime. +// +// It is an alternative to pre-main "registration" functions. +// +// Usage: +// +// // In N translation units. +// UPB_LINKARR_APPEND(foo_array) static int elems[3] = {1, 2, 3}; +// +// // At runtime: +// UPB_LINKARR_DECLARE(foo_array, int); +// +// void f() { +// const int* start = UPB_LINKARR_START(foo_array); +// const int* stop = UPB_LINKARR_STOP(foo_array); +// for (const int* p = start; p < stop; p++) { +// // Windows can introduce zero padding, so we have to skip zeroes. +// if (*p != 0) { +// vec.push_back(*p); +// } +// } +// } + +#if defined(__GNUC__) && !defined(__clang__) +// GCC can't handle mismatched retain attributes in the same section: +// https://github.com/protocolbuffers/protobuf/issues/26385 +// To work around this, we retain all linker array elements, even though this +// effectively disables tree-shaking of unused extensions when using GCC. +#define UPB_LINKARR_ATTR UPB_RETAIN +#else +#define UPB_LINKARR_ATTR +#endif + +#define UPB_LINKARR_SENTINEL UPB_RETAIN __attribute__((weak, used)) + +#if defined(__ELF__) || defined(__wasm__) + +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(__MACH__) + +/* As described in: https://stackoverflow.com/a/22366882 */ +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(_MSC_VER) + +/* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ +#define UPB_STRINGIFY_INTERNAL(x) #x +#define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) +#define UPB_CONCAT(a, b, c) a##b##c +#define UPB_LINKARR_NAME(name, index) \ + UPB_STRINGIFY(UPB_CONCAT(la_, name, index)) +#define UPB_LINKARR_APPEND(name) \ + __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $j))) +// clang-format off +#define UPB_LINKARR_DECLARE(name, type) \ + __pragma(message(UPB_LINKARR_NAME(name, $j))) \ + __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ + __pragma(section(UPB_LINKARR_NAME(name, $z), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $a)), selectany) \ + type __start_linkarr_##name; \ + __declspec(allocate(UPB_LINKARR_NAME(name, $z)), selectany) \ + type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} +// clang-format on +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#else + +// Linker arrays are not supported on this platform. Make macros no-ops. +#define UPB_LINKARR_APPEND(name) +#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_START(name) (NULL) +#define UPB_LINKARR_STOP(name) (NULL) + +#endif + +// Workaround for https://github.com/llvm/llvm-project/issues/167577 until it's +// fixed. Some function must exist for the constructor to work properly. +// TODO Remove this or gate it on a future version of clang. +#if defined(__clang__) && defined(__arm__) +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((used, visibility("hidden"))) void UPB_PRIVATE(unique_name)( \ + void) {} +#else +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) +#endif + +#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) +#define UPB_CONSTRUCTOR(name, unique_name) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ + name)(void) +#elif defined(_MSC_VER) +/* + * See: https://stackoverflow.com/questions/1113409 + * + * The /include pragma suggested in the link above doesn't work in our case + * because it requires globally unique names. We need a different solution + * to prevent optimizers from removing the constructor. Our solution is to + * create a dummy exported weak symbol that prevent this stripping. + */ +#pragma section(".CRT$XCT", read) +#define UPB_CONSTRUCTOR(name, unique_name) \ + static void __cdecl UPB_PRIVATE(name)(void); \ + __declspec(allocate(".CRT$XCT"), selectany) void( \ + __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ + __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ + &UPB_PRIVATE(name##_); \ + static void __cdecl UPB_PRIVATE(name)(void) + +#else +// No constructor support, nothing we can do except not break builds. +#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#endif + +// +// Weak alias platform support. Theoretically this should be possible to do with +// only C using attributes like __attribute__((weak, alias("foo"))), but +// Clang doesn't support this properly on macOS. So we have to use assembly. +#if defined(__APPLE__) + +// TODO: once https://github.com/llvm/llvm-project/issues/167262 is fixed +// in the LLVM linker, we should have all weak variables point to a single +// "default" empty MiniTable instead of having each leaf define its own, like +// we do with ELF below. This will reduce binary size if many messages are tree +// shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) \ + __attribute__((weak)) const upb_MiniTable name = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to; \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); \ + __asm__(".weak_definition _" #to); +#define UPB_STRONG_ALIAS(type, from, to) \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); + +#elif defined(__ELF__) + +// On ELF, weak aliases work properly, so we can have all weak MiniTables point +// to the same empty singleton MiniTable. This reduces code size if many +// MiniTables are tree shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ + __attribute__((weak)) \ + const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to \ + __attribute__((weak, alias("kUpb_WeakSingletonPlaceholderMiniTable"))); +#define UPB_STRONG_ALIAS(type, from, to) \ + extern type to __attribute__((alias(#from))); + +#else +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) weak_alias_not_supported_on_this_platform +#define UPB_STRONG_ALIAS(type, from, to) \ + strong_alias_not_supported_on_this_platform +#endif + +// Future versions of upb will include breaking changes to some APIs. +// This macro can be set to enable these API changes ahead of time, so that +// user code can be updated before upgrading versions of protobuf. +#ifdef UPB_FUTURE_BREAKING_CHANGES + +#endif + +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include <stddef.h> + +// Must be last. + +extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list); +typedef struct { + upb_MiniTableField fields[1]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__FileDescriptorSet_msg_init_Fields; + +static const google__protobuf__FileDescriptorSet_msg_init_Fields google_protobuf_FileDescriptorSet__fields = {{ + {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FileDescriptorProto_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init = { + &google_protobuf_FileDescriptorSet__fields.fields[0], + 16, 1, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FileDescriptorSet", +#endif +}; + +typedef struct { + upb_MiniTableField fields[14]; + upb_MiniTableSubInternal subs[7]; +} google__protobuf__FileDescriptorProto_msg_init_Fields; + +static const google__protobuf__FileDescriptorProto_msg_init_Fields google_protobuf_FileDescriptorProto__fields = {{ + {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FileOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init = { + &google_protobuf_FileDescriptorProto__fields.fields[0], + UPB_SIZE(80, 144), 14, kUpb_ExtMode_NonExtendable, 12, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FileDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0020000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x004000003f00001a, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x007800003f000050, &upb_DecodeFast_Varint32_Repeated_Tag1Byte}, + {0x008000003f000058, &upb_DecodeFast_Varint32_Repeated_Tag1Byte}, + {0x0030000004000062, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x008800003f00007a, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[11]; + upb_MiniTableSubInternal subs[9]; +} google__protobuf__DescriptorProto_msg_init_Fields; + +static const google__protobuf__DescriptorProto_msg_init_Fields google_protobuf_DescriptorProto__fields = {{ + {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ExtensionRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MessageOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ReservedRange_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__SymbolVisibility_enum_init}, +}}; + +const upb_MiniTable google__protobuf__DescriptorProto_msg_init = { + &google_protobuf_DescriptorProto__fields.fields[0], + UPB_SIZE(64, 104), 11, kUpb_ExtMode_NonExtendable, 11, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.DescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x006000003f000052, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__DescriptorProto__ExtensionRange_msg_init_Fields; + +static const google__protobuf__DescriptorProto__ExtensionRange_msg_init_Fields google_protobuf_DescriptorProto_ExtensionRange__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__DescriptorProto__ExtensionRange_msg_init = { + &google_protobuf_DescriptorProto_ExtensionRange__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.DescriptorProto.ExtensionRange", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; +} google__protobuf__DescriptorProto__ReservedRange_msg_init_Fields; + +static const google__protobuf__DescriptorProto__ReservedRange_msg_init_Fields google_protobuf_DescriptorProto_ReservedRange__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init = { + &google_protobuf_DescriptorProto_ReservedRange__fields.fields[0], + 24, 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.DescriptorProto.ReservedRange", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[4]; + upb_MiniTableSubInternal subs[4]; +} google__protobuf__ExtensionRangeOptions_msg_init_Fields; + +static const google__protobuf__ExtensionRangeOptions_msg_init_Fields google_protobuf_ExtensionRangeOptions__fields = {{ + {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions__Declaration_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__ExtensionRangeOptions__VerificationState_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__ExtensionRangeOptions_msg_init = { + &google_protobuf_ExtensionRangeOptions__fields.fields[0], + UPB_SIZE(32, 40), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ExtensionRangeOptions", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; +} google__protobuf__ExtensionRangeOptions__Declaration_msg_init_Fields; + +static const google__protobuf__ExtensionRangeOptions__Declaration_msg_init_Fields google_protobuf_ExtensionRangeOptions_Declaration__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_init = { + &google_protobuf_ExtensionRangeOptions_Declaration__fields.fields[0], + UPB_SIZE(32, 48), 5, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ExtensionRangeOptions.Declaration", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x002000000200001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000003000028, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000004000030, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[11]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FieldDescriptorProto_msg_init_Fields; + +static const google__protobuf__FieldDescriptorProto_msg_init_Fields google_protobuf_FieldDescriptorProto__fields = {{ + {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldDescriptorProto__Label_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldDescriptorProto__Type_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init = { + &google_protobuf_FieldDescriptorProto__fields.fields[0], + UPB_SIZE(72, 120), 11, kUpb_ExtMode_NonExtendable, 10, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0030000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x000c000002000018, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0040000005000032, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x005000000600003a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0018000008000048, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0060000009000052, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000a00000a000188, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__OneofDescriptorProto_msg_init_Fields; + +static const google__protobuf__OneofDescriptorProto_msg_init_Fields google_protobuf_OneofDescriptorProto__fields = {{ + {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init = { + &google_protobuf_OneofDescriptorProto__fields.fields[0], + UPB_SIZE(24, 40), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.OneofDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[6]; + upb_MiniTableSubInternal subs[4]; +} google__protobuf__EnumDescriptorProto_msg_init_Fields; + +static const google__protobuf__EnumDescriptorProto_msg_init_Fields google_protobuf_EnumDescriptorProto__fields = {{ + {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__SymbolVisibility_enum_init}, +}}; + +const upb_MiniTable google__protobuf__EnumDescriptorProto_msg_init = { + &google_protobuf_EnumDescriptorProto__fields.fields[0], + UPB_SIZE(40, 64), 6, kUpb_ExtMode_NonExtendable, 6, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x003800003f00002a, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; +} google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init_Fields; + +static const google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init_Fields google_protobuf_EnumDescriptorProto_EnumReservedRange__fields = {{ + {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init = { + &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields.fields[0], + 24, 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumDescriptorProto.EnumReservedRange", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000000000008, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__EnumValueDescriptorProto_msg_init_Fields; + +static const google__protobuf__EnumValueDescriptorProto_msg_init_Fields google_protobuf_EnumValueDescriptorProto__fields = {{ + {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init = { + &google_protobuf_EnumValueDescriptorProto__fields.fields[0], + UPB_SIZE(32, 40), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumValueDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x000c000001000010, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__ServiceDescriptorProto_msg_init_Fields; + +static const google__protobuf__ServiceDescriptorProto_msg_init_Fields google_protobuf_ServiceDescriptorProto__fields = {{ + {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init = { + &google_protobuf_ServiceDescriptorProto__fields.fields[0], + UPB_SIZE(32, 48), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ServiceDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[6]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__MethodDescriptorProto_msg_init_Fields; + +static const google__protobuf__MethodDescriptorProto_msg_init_Fields google_protobuf_MethodDescriptorProto__fields = {{ + {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodOptions_msg_init}, +}}; + +const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init = { + &google_protobuf_MethodDescriptorProto__fields.fields[0], + UPB_SIZE(40, 72), 6, kUpb_ExtMode_NonExtendable, 6, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.MethodDescriptorProto", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0020000001000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x003000000200001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000004000028, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000005000030, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[21]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FileOptions_msg_init_Fields; + +static const google__protobuf__FileOptions_msg_init_Fields google_protobuf_FileOptions__fields = {{ + {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FileOptions__OptimizeMode_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FileOptions_msg_init = { + &google_protobuf_FileOptions__fields.fields[0], + UPB_SIZE(112, 200), 21, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FileOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001800000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0028000001000042, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000b000003000050, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x003800000400005a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000005000180, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x000d000006000188, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x000e000007000190, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000f0000080001a0, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x005800000d0002aa, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x00100000090001b8, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x007800000f0002c2, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x00880000100002ca, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001100000a0001d8, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x00980000110002e2, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x00a80000120002ea, &upb_DecodeFast_Bytes_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001200000b0001f8, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[7]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__MessageOptions_msg_init_Fields; + +static const google__protobuf__MessageOptions_msg_init_Fields google_protobuf_MessageOptions__fields = {{ + {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__MessageOptions_msg_init = { + &google_protobuf_MessageOptions__fields.fields[0], + UPB_SIZE(24, 32), 7, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.MessageOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000008, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000001000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000b000002000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000003000038, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000d000004000058, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[14]; + upb_MiniTableSubInternal subs[8]; +} google__protobuf__FieldOptions_msg_init_Fields; + +static const google__protobuf__FieldOptions_msg_init_Fields google_protobuf_FieldOptions__fields = {{ + {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__CType_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__JSType_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__OptionRetention_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FieldOptions__OptionTargetType_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__EditionDefault_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__FeatureSupport_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FieldOptions_msg_init = { + &google_protobuf_FieldOptions__fields.fields[0], + UPB_SIZE(48, 72), 14, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000a000001000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000b000002000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000c000003000028, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000d000005000050, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000e000006000078, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000f000007000180, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__FieldOptions__EditionDefault_msg_init_Fields; + +static const google__protobuf__FieldOptions__EditionDefault_msg_init_Fields google_protobuf_FieldOptions_EditionDefault__fields = {{ + {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init = { + &google_protobuf_FieldOptions_EditionDefault__fields.fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldOptions.EditionDefault", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0010000000000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FieldOptions__FeatureSupport_msg_init_Fields; + +static const google__protobuf__FieldOptions__FeatureSupport_msg_init_Fields google_protobuf_FieldOptions_FeatureSupport__fields = {{ + {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FieldOptions__FeatureSupport_msg_init = { + &google_protobuf_FieldOptions_FeatureSupport__fields.fields[0], + UPB_SIZE(40, 56), 5, kUpb_ExtMode_NonExtendable, 5, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FieldOptions.FeatureSupport", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001800000200001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002800000400002a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__OneofOptions_msg_init_Fields; + +static const google__protobuf__OneofOptions_msg_init_Fields google_protobuf_OneofOptions__fields = {{ + {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__OneofOptions_msg_init = { + &google_protobuf_OneofOptions__fields.fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.OneofOptions", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__EnumOptions_msg_init_Fields; + +static const google__protobuf__EnumOptions_msg_init_Fields google_protobuf_EnumOptions__fields = {{ + {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__EnumOptions_msg_init = { + &google_protobuf_EnumOptions__fields.fields[0], + UPB_SIZE(24, 32), 5, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x000a000001000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000b000002000030, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__EnumValueOptions_msg_init_Fields; + +static const google__protobuf__EnumValueOptions_msg_init_Fields google_protobuf_EnumValueOptions__fields = {{ + {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__FeatureSupport_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__EnumValueOptions_msg_init = { + &google_protobuf_EnumValueOptions__fields.fields[0], + UPB_SIZE(24, 40), 5, kUpb_ExtMode_Extendable, 4, UPB_FASTTABLE_MASK(24), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.EnumValueOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000008, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x000a000002000018, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + }) +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[2]; +} google__protobuf__ServiceOptions_msg_init_Fields; + +static const google__protobuf__ServiceOptions_msg_init_Fields google_protobuf_ServiceOptions__fields = {{ + {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__ServiceOptions_msg_init = { + &google_protobuf_ServiceOptions__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.ServiceOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000288, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[4]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__MethodOptions_msg_init_Fields; + +static const google__protobuf__MethodOptions_msg_init_Fields google_protobuf_MethodOptions__fields = {{ + {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, + {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__MethodOptions__IdempotencyLevel_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, +}}; + +const upb_MiniTable google__protobuf__MethodOptions_msg_init = { + &google_protobuf_MethodOptions__fields.fields[0], + UPB_SIZE(24, 32), 4, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.MethodOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0009000000000288, &upb_DecodeFast_Bool_Scalar_Tag2Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[7]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__UninterpretedOption_msg_init_Fields; + +static const google__protobuf__UninterpretedOption_msg_init_Fields google_protobuf_UninterpretedOption__fields = {{ + {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}, + {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption__NamePart_msg_init}, +}}; + +const upb_MiniTable google__protobuf__UninterpretedOption_msg_init = { + &google_protobuf_UninterpretedOption__fields.fields[0], + UPB_SIZE(64, 96), 7, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(120), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.UninterpretedOption", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0048000001000020, &upb_DecodeFast_Varint64_Scalar_Tag1Byte}, + {0x0050000002000028, &upb_DecodeFast_Varint64_Scalar_Tag1Byte}, + {0x0058000003000031, &upb_DecodeFast_Fixed64_Scalar_Tag1Byte}, + {0x002000000400003a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0030000005000042, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[2]; +} google__protobuf__UninterpretedOption__NamePart_msg_init_Fields; + +static const google__protobuf__UninterpretedOption__NamePart_msg_init_Fields google_protobuf_UninterpretedOption_NamePart__fields = {{ + {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init = { + &google_protobuf_UninterpretedOption_NamePart__fields.fields[0], + UPB_SIZE(24, 32), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 2, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.UninterpretedOption.NamePart", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x001000000000000a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0009000001000010, &upb_DecodeFast_Bool_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[8]; + upb_MiniTableSubInternal subs[8]; +} google__protobuf__FeatureSet_msg_init_Fields; + +static const google__protobuf__FeatureSet_msg_init_Fields google_protobuf_FeatureSet__fields = {{ + {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__FieldPresence_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__EnumType_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__Utf8Validation_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__MessageEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__JsonFormat_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__EnforceNamingStyle_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FeatureSet_msg_init = { + &google_protobuf_FeatureSet__fields.fields[0], + 48, 8, kUpb_ExtMode_Extendable, 8, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSet", +#endif +}; + +const upb_MiniTable google__protobuf__FeatureSet__VisibilityFeature_msg_init = { + NULL, + 8, 0, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSet.VisibilityFeature", +#endif +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FeatureSetDefaults_msg_init_Fields; + +static const google__protobuf__FeatureSetDefaults_msg_init_Fields google_protobuf_FeatureSetDefaults__fields = {{ + {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, +}}; + +const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init = { + &google_protobuf_FeatureSetDefaults__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSetDefaults", +#endif +}; + +typedef struct { + upb_MiniTableField fields[3]; + upb_MiniTableSubInternal subs[3]; +} google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init_Fields; + +static const google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init_Fields google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__fields = {{ + {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, +}}; + +const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init = { + &google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__fields.fields[0], + UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 0, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault", +#endif +}; + +typedef struct { + upb_MiniTableField fields[1]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__SourceCodeInfo_msg_init_Fields; + +static const google__protobuf__SourceCodeInfo_msg_init_Fields google_protobuf_SourceCodeInfo__fields = {{ + {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo__Location_msg_init}, +}}; + +const upb_MiniTable google__protobuf__SourceCodeInfo_msg_init = { + &google_protobuf_SourceCodeInfo__fields.fields[0], + 16, 1, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.SourceCodeInfo", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; +} google__protobuf__SourceCodeInfo__Location_msg_init_Fields; + +static const google__protobuf__SourceCodeInfo__Location_msg_init_Fields google_protobuf_SourceCodeInfo_Location__fields = {{ + {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init = { + &google_protobuf_SourceCodeInfo_Location__fields.fields[0], + UPB_SIZE(40, 72), 5, kUpb_ExtMode_NonExtendable, 4, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.SourceCodeInfo.Location", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x003000003f00000a, &upb_DecodeFast_Varint32_Packed_Tag1Byte}, + {0x003800003f000012, &upb_DecodeFast_Varint32_Packed_Tag1Byte}, + {0x001000000000001a, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0020000001000022, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x004000003f000032, &upb_DecodeFast_Bytes_Repeated_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +typedef struct { + upb_MiniTableField fields[1]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__GeneratedCodeInfo_msg_init_Fields; + +static const google__protobuf__GeneratedCodeInfo_msg_init_Fields google_protobuf_GeneratedCodeInfo__fields = {{ + {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(submsg) = &google__protobuf__GeneratedCodeInfo__Annotation_msg_init}, +}}; + +const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init = { + &google_protobuf_GeneratedCodeInfo__fields.fields[0], + 16, 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(255), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.GeneratedCodeInfo", +#endif +}; + +typedef struct { + upb_MiniTableField fields[5]; + upb_MiniTableSubInternal subs[1]; +} google__protobuf__GeneratedCodeInfo__Annotation_msg_init_Fields; + +static const google__protobuf__GeneratedCodeInfo__Annotation_msg_init_Fields google_protobuf_GeneratedCodeInfo_Annotation__fields = {{ + {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, + {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}, + }, + { + {.UPB_PRIVATE(subenum) = &google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init}, +}}; + +const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init = { + &google_protobuf_GeneratedCodeInfo_Annotation__fields.fields[0], + UPB_SIZE(40, 48), 5, kUpb_ExtMode_NonExtendable, 5, UPB_FASTTABLE_MASK(56), 0, +#ifdef UPB_TRACING_ENABLED + "google.protobuf.GeneratedCodeInfo.Annotation", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x002800003f00000a, &upb_DecodeFast_Varint32_Packed_Tag1Byte}, + {0x0018000000000012, &upb_DecodeFast_Bytes_Scalar_Tag1Byte}, + {0x000c000001000018, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0010000002000020, &upb_DecodeFast_Varint32_Scalar_Tag1Byte}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric}, + }) +}; + +const upb_MiniTableEnum google__protobuf__Edition_enum_init = { + 64, + 11, + { + 0x7, + 0x0, + 0x384, + 0x3e6, + 0x3e7, + 0x3e8, + 0x3e9, + 0x3ea, + 0x270f, + 0x1869d, + 0x1869e, + 0x1869f, + 0x7fffffff, + }, +}; + +const upb_MiniTableEnum google__protobuf__ExtensionRangeOptions__VerificationState_enum_init = { + 64, + 0, + { + 0x3, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__EnforceNamingStyle_enum_init = { + 64, + 0, + { + 0xf, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__EnumType_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__FieldPresence_enum_init = { + 64, + 0, + { + 0xf, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__JsonFormat_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__MessageEncoding_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__Utf8Validation_enum_init = { + 64, + 0, + { + 0xd, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init = { + 64, + 0, + { + 0x1f, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Label_enum_init = { + 64, + 0, + { + 0xe, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Type_enum_init = { + 64, + 0, + { + 0x7fffe, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__CType_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__JSType_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__OptionRetention_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FieldOptions__OptionTargetType_enum_init = { + 64, + 0, + { + 0x3ff, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__FileOptions__OptimizeMode_enum_init = { + 64, + 0, + { + 0xe, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__MethodOptions__IdempotencyLevel_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = { + 64, + 0, + { + 0x7, + 0x0, + }, +}; + +static const upb_MiniTable *messages_layout[34] = { + &google__protobuf__FileDescriptorSet_msg_init, + &google__protobuf__FileDescriptorProto_msg_init, + &google__protobuf__DescriptorProto_msg_init, + &google__protobuf__DescriptorProto__ExtensionRange_msg_init, + &google__protobuf__DescriptorProto__ReservedRange_msg_init, + &google__protobuf__ExtensionRangeOptions_msg_init, + &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, + &google__protobuf__FieldDescriptorProto_msg_init, + &google__protobuf__OneofDescriptorProto_msg_init, + &google__protobuf__EnumDescriptorProto_msg_init, + &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, + &google__protobuf__EnumValueDescriptorProto_msg_init, + &google__protobuf__ServiceDescriptorProto_msg_init, + &google__protobuf__MethodDescriptorProto_msg_init, + &google__protobuf__FileOptions_msg_init, + &google__protobuf__MessageOptions_msg_init, + &google__protobuf__FieldOptions_msg_init, + &google__protobuf__FieldOptions__EditionDefault_msg_init, + &google__protobuf__FieldOptions__FeatureSupport_msg_init, + &google__protobuf__OneofOptions_msg_init, + &google__protobuf__EnumOptions_msg_init, + &google__protobuf__EnumValueOptions_msg_init, + &google__protobuf__ServiceOptions_msg_init, + &google__protobuf__MethodOptions_msg_init, + &google__protobuf__UninterpretedOption_msg_init, + &google__protobuf__UninterpretedOption__NamePart_msg_init, + &google__protobuf__FeatureSet_msg_init, + &google__protobuf__FeatureSet__VisibilityFeature_msg_init, + &google__protobuf__FeatureSetDefaults_msg_init, + &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, + &google__protobuf__SourceCodeInfo_msg_init, + &google__protobuf__SourceCodeInfo__Location_msg_init, + &google__protobuf__GeneratedCodeInfo_msg_init, + &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, +}; + +static const upb_MiniTableEnum *enums_layout[20] = { + &google__protobuf__Edition_enum_init, + &google__protobuf__ExtensionRangeOptions__VerificationState_enum_init, + &google__protobuf__FeatureSet__EnforceNamingStyle_enum_init, + &google__protobuf__FeatureSet__EnumType_enum_init, + &google__protobuf__FeatureSet__FieldPresence_enum_init, + &google__protobuf__FeatureSet__JsonFormat_enum_init, + &google__protobuf__FeatureSet__MessageEncoding_enum_init, + &google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init, + &google__protobuf__FeatureSet__Utf8Validation_enum_init, + &google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init, + &google__protobuf__FieldDescriptorProto__Label_enum_init, + &google__protobuf__FieldDescriptorProto__Type_enum_init, + &google__protobuf__FieldOptions__CType_enum_init, + &google__protobuf__FieldOptions__JSType_enum_init, + &google__protobuf__FieldOptions__OptionRetention_enum_init, + &google__protobuf__FieldOptions__OptionTargetType_enum_init, + &google__protobuf__FileOptions__OptimizeMode_enum_init, + &google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init, + &google__protobuf__MethodOptions__IdempotencyLevel_enum_init, + &google__protobuf__SymbolVisibility_enum_init, +}; + +const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { + messages_layout, + enums_layout, + NULL, + 34, + 20, + 0, +}; + + + + +#include <errno.h> +#include <float.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +// Must be last. + +void upb_Status_Clear(upb_Status* status) { + if (!status) return; + status->ok = true; + status->msg[0] = '\0'; +} + +bool upb_Status_IsOk(const upb_Status* status) { return status->ok; } + +const char* upb_Status_ErrorMessage(const upb_Status* status) { + return status->msg; +} + +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg) { + if (!status) return; + status->ok = false; + strncpy(status->msg, msg, _kUpb_Status_MaxMessage - 1); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; +} + +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + upb_Status_VSetErrorFormat(status, fmt, args); + va_end(args); +} + +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) { + if (!status) return; + status->ok = false; + vsnprintf(status->msg, sizeof(status->msg), fmt, args); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; +} + +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) { + size_t len; + if (!status) return; + status->ok = false; + len = strlen(status->msg); + vsnprintf(status->msg + len, sizeof(status->msg) - len, fmt, args); + status->msg[_kUpb_Status_MaxMessage - 1] = '\0'; +} + +/* + * upb_table Implementation + * + * Implementation is heavily inspired by Lua's ltable.c. + */ + + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +#define UPB_MAXARRSIZE 16 // 2**16 = 64k. + +// From Chromium. +#define ARRAY_SIZE(x) \ + ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x]))))) + +/* The minimum utilization of the array part of a mixed hash/array table. This + * is a speed/memory-usage tradeoff (though it's not straightforward because of + * cache effects). The lower this is, the more memory we'll use. */ +static const double MIN_DENSITY = 0.1; + +#if defined(__has_builtin) +#if __has_builtin(__builtin_popcount) +#define UPB_FAST_POPCOUNT32(i) __builtin_popcount(i) +#endif +#elif defined(__GNUC__) +#define UPB_FAST_POPCOUNT32(i) __builtin_popcount(i) +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) +// Only use __popcnt on x86/x64 architectures for MSVC +#define UPB_FAST_POPCOUNT32(i) __popcnt(i) +#endif + +UPB_INLINE int _upb_popcnt32(uint32_t i) { +#ifdef UPB_FAST_POPCOUNT32 + return UPB_FAST_POPCOUNT32(i); +#else + int count = 0; + while (i != 0) { + count += i & 1; + i >>= 1; + } + return count; +#endif +} + +#undef UPB_FAST_POPCOUNT32 + +UPB_INLINE uint8_t _upb_log2_table_size(upb_table* t) { + return _upb_popcnt32(t->mask); +} + +static bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; } + +static int log2ceil(uint64_t v) { + int ret = 0; + bool pow2 = is_pow2(v); + while (v >>= 1) ret++; + ret = pow2 ? ret : ret + 1; // Ceiling. + return UPB_MIN(UPB_MAXARRSIZE, ret); +} + +/* A type to represent the lookup key of either a strtable, inttable or + * exttable. */ +typedef union { + uintptr_t num; + upb_StringView str; + struct { + const void* ptr; + uint32_t ext_num; + } ext; +} lookupkey_t; + +static lookupkey_t strkey2(const char* str, size_t len) { + return (lookupkey_t){.str = upb_StringView_FromDataAndSize(str, len)}; +} + +static lookupkey_t intkey(uintptr_t key) { return (lookupkey_t){.num = key}; } + +static lookupkey_t extkey(const void* ptr, uint32_t ext_num) { + return (lookupkey_t){.ext = {ptr, ext_num}}; +} + +// Conceptually the hash and equal functions should only take the key, not the +// value, but the extension table stores part of its logical key in the value +// slot. This is a sign that we have outgrown the original architecture. +typedef uint32_t hashfunc_t(upb_key key, upb_value val); +typedef bool eqlfunc_t(upb_key k1, upb_value v1, lookupkey_t k2); + +/* Base table (shared code) ***************************************************/ + +static uint32_t upb_inthash(uintptr_t key) { + UPB_STATIC_ASSERT(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8, + "Pointers don't fit"); + if (sizeof(uintptr_t) == 8) { + return (uint32_t)key ^ (uint32_t)(key >> 32); + } else { + return (uint32_t)key; + } +} + +static const upb_tabent* upb_getentry(const upb_table* t, uint32_t hash) { + return t->entries + (hash & t->mask); +} + +static bool isfull(upb_table* t) { + uint32_t size = upb_table_size(t); + // 0.875 load factor + return t->count == (size - (size >> 3)); +} + +static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) { + if (size_lg2 >= 32) { + return false; + } + t->count = 0; + uint32_t size = 1 << size_lg2; + t->mask = size - 1; // 0 mask if size_lg2 is 0 + if (upb_table_size(t) > (SIZE_MAX / sizeof(upb_tabent))) { + return false; + } + size_t bytes = upb_table_size(t) * sizeof(upb_tabent); + if (bytes > 0) { + t->entries = upb_Arena_Malloc(a, bytes); + if (!t->entries) return false; + memset(t->entries, 0, bytes); + } else { + t->entries = NULL; + } + return true; +} + +static upb_tabent* emptyent(upb_table* t, upb_tabent* e) { + upb_tabent* begin = t->entries; + upb_tabent* end = begin + upb_table_size(t); + for (e = e + 1; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + for (e = begin; e < end; e++) { + if (upb_tabent_isempty(e)) return e; + } + UPB_ASSERT(false); + return NULL; +} + +static upb_tabent* getentry_mutable(upb_table* t, uint32_t hash) { + return (upb_tabent*)upb_getentry(t, hash); +} + +static const upb_tabent* findentry(const upb_table* t, lookupkey_t key, + uint32_t hash, eqlfunc_t* eql) { + const upb_tabent* e; + + if (t->count == 0) return NULL; + e = upb_getentry(t, hash); + if (upb_tabent_isempty(e)) return NULL; + while (1) { + if (eql(e->key, e->val, key)) return e; + if ((e = e->next) == NULL) return NULL; + } +} + +static upb_tabent* findentry_mutable(upb_table* t, lookupkey_t key, + uint32_t hash, eqlfunc_t* eql) { + return (upb_tabent*)findentry(t, key, hash, eql); +} + +static bool lookup(const upb_table* t, lookupkey_t key, upb_value* v, + uint32_t hash, eqlfunc_t* eql) { + const upb_tabent* e = findentry(t, key, hash, eql); + if (e) { + if (v) *v = e->val; + return true; + } else { + return false; + } +} + +/* The given key must not already exist in the table. */ +static void insert(upb_table* t, lookupkey_t key, upb_key tabkey, upb_value val, + uint32_t hash, hashfunc_t* hashfunc, eqlfunc_t* eql) { + upb_tabent* mainpos_e; + upb_tabent* our_e; + + UPB_ASSERT(findentry(t, key, hash, eql) == NULL); + + t->count++; + mainpos_e = getentry_mutable(t, hash); + our_e = mainpos_e; + + if (upb_tabent_isempty(mainpos_e)) { + /* Our main position is empty; use it. */ + our_e->next = NULL; + } else { + /* Collision. */ + upb_tabent* new_e = emptyent(t, mainpos_e); + /* Head of collider's chain. */ + upb_tabent* chain = + getentry_mutable(t, hashfunc(mainpos_e->key, mainpos_e->val)); + if (chain == mainpos_e) { + /* Existing ent is in its main position (it has the same hash as us, and + * is the head of our chain). Insert to new ent and append to this chain. + */ + new_e->next = mainpos_e->next; + mainpos_e->next = new_e; + our_e = new_e; + } else { + /* Existing ent is not in its main position (it is a node in some other + * chain). This implies that no existing ent in the table has our hash. + * Evict it (updating its chain) and use its ent for head of our chain. */ + *new_e = *mainpos_e; /* copies next. */ + while (chain->next != mainpos_e) { + chain = (upb_tabent*)chain->next; + UPB_ASSERT(chain); + } + chain->next = new_e; + our_e = mainpos_e; + our_e->next = NULL; + } + } + our_e->key = tabkey; + our_e->val = val; + UPB_ASSERT(findentry(t, key, hash, eql) == our_e); +} + +static bool rm(upb_table* t, lookupkey_t key, upb_value* val, uint32_t hash, + eqlfunc_t* eql) { + upb_tabent* chain = getentry_mutable(t, hash); + if (upb_tabent_isempty(chain)) return false; + if (eql(chain->key, chain->val, key)) { + /* Element to remove is at the head of its chain. */ + t->count--; + if (val) *val = chain->val; + if (chain->next) { + upb_tabent* move = (upb_tabent*)chain->next; + *chain = *move; + move->key = upb_key_empty(); + } else { + chain->key = upb_key_empty(); + } + return true; + } else { + /* Element to remove is either in a non-head position or not in the + * table. */ + while (chain->next && !eql(chain->next->key, chain->next->val, key)) { + chain = (upb_tabent*)chain->next; + } + if (chain->next) { + /* Found element to remove. */ + upb_tabent* rm = (upb_tabent*)chain->next; + t->count--; + if (val) *val = chain->next->val; + rm->key = upb_key_empty(); + chain->next = rm->next; + return true; + } else { + /* Element to remove is not in the table. */ + return false; + } + } +} + +static size_t next(const upb_table* t, size_t i) { + do { + if (++i >= upb_table_size(t)) return SIZE_MAX - 1; /* Distinct from -1. */ + } while (upb_tabent_isempty(&t->entries[i])); + + return i; +} + +static size_t begin(const upb_table* t) { return next(t, -1); } + +/* upb_strtable ***************************************************************/ + +// A simple "subclass" of upb_table that only adds a hash function for strings. + +static upb_SizePrefixString* upb_SizePrefixString_Copy(upb_StringView s, + upb_Arena* a) { + // A 2GB string will fail at serialization time, but we accept up to 4GB in + // memory here. + if (s.size > UINT32_MAX) return NULL; + upb_SizePrefixString* str = + upb_Arena_Malloc(a, sizeof(uint32_t) + s.size + 1); + if (str == NULL) return NULL; + str->size = s.size; + char* data = (char*)str->data; + if (s.size) memcpy(data, s.data, s.size); + data[s.size] = '\0'; + return str; +} + +/* Adapted from ABSL's wyhash. */ + +static uint64_t UnalignedLoad64(const void* p) { + uint64_t val; + memcpy(&val, p, 8); + return val; +} + +static uint32_t UnalignedLoad32(const void* p) { + uint32_t val; + memcpy(&val, p, 4); + return val; +} + +#if defined(_MSC_VER) && defined(_M_X64) +#include <intrin.h> +#endif + +/* Computes a * b, returning the low 64 bits of the result and storing the high + * 64 bits in |*high|. */ +static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t* out_high) { +#ifdef __SIZEOF_INT128__ + __uint128_t p = v0; + p *= v1; + *out_high = (uint64_t)(p >> 64); + return (uint64_t)p; +#elif defined(_MSC_VER) && defined(_M_X64) + return _umul128(v0, v1, out_high); +#else + uint64_t a32 = v0 >> 32; + uint64_t a00 = v0 & 0xffffffff; + uint64_t b32 = v1 >> 32; + uint64_t b00 = v1 & 0xffffffff; + uint64_t high = a32 * b32; + uint64_t low = a00 * b00; + uint64_t mid1 = a32 * b00; + uint64_t mid2 = a00 * b32; + low += (mid1 << 32) + (mid2 << 32); + // Omit carry bit, for mixing we do not care about exact numerical precision. + high += (mid1 >> 32) + (mid2 >> 32); + *out_high = high; + return low; +#endif +} + +static uint64_t WyhashMix(uint64_t v0, uint64_t v1) { + uint64_t high; + uint64_t low = upb_umul128(v0, v1, &high); + return low ^ high; +} + +static uint64_t Wyhash(const void* data, size_t len, uint64_t seed, + const uint64_t salt[]) { + const uint8_t* ptr = (const uint8_t*)data; + uint64_t starting_length = (uint64_t)len; + uint64_t current_state = seed ^ salt[0]; + + if (len > 64) { + // If we have more than 64 bytes, we're going to handle chunks of 64 + // bytes at a time. We're going to build up two separate hash states + // which we will then hash together. + uint64_t duplicated_state = current_state; + + do { + uint64_t a = UnalignedLoad64(ptr); + uint64_t b = UnalignedLoad64(ptr + 8); + uint64_t c = UnalignedLoad64(ptr + 16); + uint64_t d = UnalignedLoad64(ptr + 24); + uint64_t e = UnalignedLoad64(ptr + 32); + uint64_t f = UnalignedLoad64(ptr + 40); + uint64_t g = UnalignedLoad64(ptr + 48); + uint64_t h = UnalignedLoad64(ptr + 56); + + uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state); + uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state); + current_state = (cs0 ^ cs1); + + uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state); + uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state); + duplicated_state = (ds0 ^ ds1); + + ptr += 64; + len -= 64; + } while (len > 64); + + current_state = current_state ^ duplicated_state; + } + + // We now have a data `ptr` with at most 64 bytes and the current state + // of the hashing state machine stored in current_state. + while (len > 16) { + uint64_t a = UnalignedLoad64(ptr); + uint64_t b = UnalignedLoad64(ptr + 8); + + current_state = WyhashMix(a ^ salt[1], b ^ current_state); + + ptr += 16; + len -= 16; + } + + // We now have a data `ptr` with at most 16 bytes. + uint64_t a = 0; + uint64_t b = 0; + if (len > 8) { + // When we have at least 9 and at most 16 bytes, set A to the first 64 + // bits of the input and B to the last 64 bits of the input. Yes, they will + // overlap in the middle if we are working with less than the full 16 + // bytes. + a = UnalignedLoad64(ptr); + b = UnalignedLoad64(ptr + len - 8); + } else if (len > 3) { + // If we have at least 4 and at most 8 bytes, set A to the first 32 + // bits and B to the last 32 bits. + a = UnalignedLoad32(ptr); + b = UnalignedLoad32(ptr + len - 4); + } else if (len > 0) { + // If we have at least 1 and at most 3 bytes, read all of the provided + // bits into A, with some adjustments. + a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]); + b = 0; + } else { + a = 0; + b = 0; + } + + uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state); + uint64_t z = salt[1] ^ starting_length; + return WyhashMix(w, z); +} + +const uint64_t kWyhashSalt[5] = { + 0x243F6A8885A308D3ULL, 0x13198A2E03707344ULL, 0xA4093822299F31D0ULL, + 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL, +}; + +uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed) { + return Wyhash(p, n, seed, kWyhashSalt); +} + +static const void* const _upb_seed; + +// Returns a random seed for upb's hash function. This does not provide +// high-quality randomness, but it should be enough to prevent unit tests from +// relying on a deterministic map ordering. By returning the address of a +// variable, we are able to get some randomness for free provided that ASLR is +// enabled. +static uint64_t _upb_Seed(void) { return (uint64_t)&_upb_seed; } + +static uint32_t _upb_Hash_NoSeed(const char* p, size_t n) { + return _upb_Hash(p, n, _upb_Seed()); +} + +static uint32_t strhash(upb_key key, upb_value val) { + UPB_UNUSED(val); + return _upb_Hash_NoSeed(key.str->data, key.str->size); +} + +static bool streql(upb_key k1, upb_value v1, lookupkey_t k2) { + UPB_UNUSED(v1); + const upb_SizePrefixString* k1s = k1.str; + const upb_StringView k2s = k2.str; + return k1s->size == k2s.size && + (k1s->size == 0 || memcmp(k1s->data, k2s.data, k1s->size) == 0); +} + +/** Calculates the number of entries required to hold an expected number of + * values, within the table's load factor. */ +static size_t _upb_entries_needed_for(size_t expected_size) { + size_t need_entries = expected_size + 1 + expected_size / 7; + UPB_ASSERT(need_entries - (need_entries >> 3) >= expected_size); + return need_entries; +} + +bool upb_strtable_init(upb_strtable* t, size_t expected_size, upb_Arena* a) { + int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size)); + return init(&t->t, size_lg2, a); +} + +void upb_strtable_clear(upb_strtable* t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a) { + upb_strtable new_table; + if (!init(&new_table.t, size_lg2, a)) return false; + + intptr_t iter = UPB_STRTABLE_BEGIN; + upb_StringView sv; + upb_value val; + while (upb_strtable_next2(t, &sv, &val, &iter)) { + // Unlike normal insert, does not copy string data or possibly reallocate + // the table + // The data pointer used in the table is guaranteed to point at a + // upb_SizePrefixString, we just need to back up by the size of the uint32_t + // length prefix. + const upb_SizePrefixString* keystr = + (const upb_SizePrefixString*)(sv.data - sizeof(uint32_t)); + UPB_ASSERT(keystr->data == sv.data); + UPB_ASSERT(keystr->size == sv.size); + + lookupkey_t lookupkey = {.str = sv}; + upb_key tabkey = {.str = keystr}; + uint32_t hash = _upb_Hash_NoSeed(sv.data, sv.size); + insert(&new_table.t, lookupkey, tabkey, val, hash, &strhash, &streql); + } + *t = new_table; + return true; +} + +bool upb_strtable_insert(upb_strtable* t, const char* k, size_t len, + upb_value v, upb_Arena* a) { + if (isfull(&t->t)) { + /* Need to resize. New table of double the size, add old elements to it. */ + if (!upb_strtable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) { + return false; + } + } + + upb_StringView sv = upb_StringView_FromDataAndSize(k, len); + upb_SizePrefixString* size_prefix_string = upb_SizePrefixString_Copy(sv, a); + if (!size_prefix_string) return false; + + lookupkey_t lookupkey = {.str = sv}; + upb_key key = {.str = size_prefix_string}; + uint32_t hash = _upb_Hash_NoSeed(k, len); + insert(&t->t, lookupkey, key, v, hash, &strhash, &streql); + return true; +} + +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v) { + uint32_t hash = _upb_Hash_NoSeed(key, len); + return lookup(&t->t, strkey2(key, len), v, hash, &streql); +} + +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val) { + uint32_t hash = _upb_Hash_NoSeed(key, len); + return rm(&t->t, strkey2(key, len), val, hash, &streql); +} + +/* Iteration */ + +void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t) { + i->t = t; + i->index = begin(&t->t); +} + +void upb_strtable_next(upb_strtable_iter* i) { + i->index = next(&i->t->t, i->index); +} + +bool upb_strtable_done(const upb_strtable_iter* i) { + if (!i->t) return true; + return i->index >= upb_table_size(&i->t->t) || + upb_tabent_isempty(str_tabent(i)); +} + +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i) { + UPB_ASSERT(!upb_strtable_done(i)); + return upb_key_strview(str_tabent(i)->key); +} + +upb_value upb_strtable_iter_value(const upb_strtable_iter* i) { + UPB_ASSERT(!upb_strtable_done(i)); + return str_tabent(i)->val; +} + +void upb_strtable_iter_setdone(upb_strtable_iter* i) { + i->t = NULL; + i->index = SIZE_MAX; +} + +bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, + const upb_strtable_iter* i2) { + if (upb_strtable_done(i1) && upb_strtable_done(i2)) return true; + return i1->t == i2->t && i1->index == i2->index; +} + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter) { + size_t tab_idx = next(&t->t, *iter); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + *key = upb_key_strview(ent->key); + *val = ent->val; + *iter = tab_idx; + return true; + } + + return false; +} + +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter) { + intptr_t i = *iter; + upb_tabent* ent = &t->t.entries[i]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = upb_key_empty(); + ent->next = NULL; +} + +void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v) { + t->t.entries[iter].val = v; +} + +/* upb_exttable ***************************************************************/ + +static uint32_t _upb_exttable_hash(const void* ptr, uint32_t ext_num) { + uint64_t a = (uintptr_t)ptr; + uint64_t b = ext_num; + return (uint32_t)WyhashMix(a ^ kWyhashSalt[1], b ^ _upb_Seed()); +} + +static uint32_t exthash(upb_key key, upb_value val) { + const void* ptr = (const void*)key.num; + uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(val); + return _upb_exttable_hash(ptr, ext_num); +} + +static bool exteql(upb_key k1, upb_value v1, lookupkey_t k2) { + if ((const void*)k1.num == k2.ext.ptr) { + uint32_t ext_num1 = *(const uint32_t*)upb_value_getconstptr(v1); + return ext_num1 == k2.ext.ext_num; + } + return false; +} + +bool upb_exttable_init(upb_exttable* t, size_t expected_size, upb_Arena* a) { + int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size)); + return init(&t->t, size_lg2, a); +} + +void upb_exttable_clear(upb_exttable* t) { + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +bool upb_exttable_resize(upb_exttable* t, size_t size_lg2, upb_Arena* a) { + upb_exttable new_table; + if (!init(&new_table.t, size_lg2, a)) return false; + + size_t i; + for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { + const upb_tabent* e = &t->t.entries[i]; + uint32_t hash = exthash(e->key, e->val); + uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(e->val); + lookupkey_t lookupkey = extkey((const void*)e->key.num, ext_num); + insert(&new_table.t, lookupkey, e->key, e->val, hash, &exthash, &exteql); + } + + *t = new_table; + return true; +} + +bool upb_exttable_insert(upb_exttable* t, const void* k, const uint32_t* v, + upb_Arena* a) { + UPB_ASSERT(k != NULL); + UPB_ASSERT(v != NULL); + UPB_ASSERT(*v != 0); + + if (isfull(&t->t)) { + if (!upb_exttable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) { + return false; + } + } + + lookupkey_t lookupkey = extkey(k, *v); + upb_key key = {.num = (uintptr_t)k}; + upb_value val = upb_value_constptr(v); + uint32_t hash = _upb_exttable_hash(k, *v); + insert(&t->t, lookupkey, key, val, hash, &exthash, &exteql); + return true; +} + +const uint32_t* upb_exttable_lookup(const upb_exttable* t, const void* k, + uint32_t ext_number) { + uint32_t hash = _upb_exttable_hash(k, ext_number); + upb_value val; + if (lookup(&t->t, extkey(k, ext_number), &val, hash, &exteql)) { + return (const uint32_t*)upb_value_getconstptr(val); + } + return NULL; +} + +const uint32_t* upb_exttable_remove(upb_exttable* t, const void* k, + uint32_t ext_number) { + uint32_t hash = _upb_exttable_hash(k, ext_number); + upb_value val; + if (rm(&t->t, extkey(k, ext_number), &val, hash, &exteql)) { + return (const uint32_t*)upb_value_getconstptr(val); + } + return NULL; +} + +size_t upb_exttable_size(const upb_exttable* t) { return t->t.count; } + +/* upb_inttable ***************************************************************/ + +/* For inttables we use a hybrid structure where small keys are kept in an + * array and large keys are put in the hash table. */ + +// The sentinel value used in the dense array part. Note that callers must +// ensure that inttable is never used with a value of this sentinel type +// (pointers and u32 values will never be; i32 needs to be handled carefully +// to avoid sign-extending into this value). +static const upb_value kInttableSentinel = {.val = UINT64_MAX}; +static uint32_t presence_mask_arr_size(uint32_t array_size) { + return (array_size + 7) / 8; // sizeof(uint8_t) is always 1. +} + +static uint32_t inthash(upb_key key, upb_value val) { + UPB_UNUSED(val); + return upb_inthash(key.num); +} + +static bool inteql(upb_key k1, upb_value v1, lookupkey_t k2) { + UPB_UNUSED(v1); + return k1.num == k2.num; +} + +static upb_value* mutable_array(upb_inttable* t) { + return (upb_value*)t->array; +} + +static const upb_value* inttable_array_get(const upb_inttable* t, + uintptr_t key) { + UPB_ASSERT(key < t->array_size); + const upb_value* val = &t->array[key]; + return upb_inttable_arrhas(t, key) ? val : NULL; +} + +static upb_value* inttable_val(upb_inttable* t, uintptr_t key) { + if (key < t->array_size) { + return (upb_value*)inttable_array_get(t, key); + } else { + upb_tabent* e = + findentry_mutable(&t->t, intkey(key), upb_inthash(key), &inteql); + return e ? &e->val : NULL; + } +} + +static const upb_value* inttable_val_const(const upb_inttable* t, + uintptr_t key) { + return inttable_val((upb_inttable*)t, key); +} + +size_t upb_inttable_count(const upb_inttable* t) { + return t->t.count + t->array_count; +} + +static void check(upb_inttable* t) { + UPB_UNUSED(t); +#if defined(UPB_DEBUG_TABLE) && !defined(NDEBUG) + { + // This check is very expensive (makes inserts/deletes O(N)). + size_t count = 0; + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + while (upb_inttable_next(t, &key, &val, &iter)) { + UPB_ASSERT(upb_inttable_lookup(t, key, NULL)); + } + UPB_ASSERT(count == upb_inttable_count(t)); + } +#endif +} + +bool upb_inttable_sizedinit(upb_inttable* t, uint32_t asize, int hsize_lg2, + upb_Arena* a) { + if (!init(&t->t, hsize_lg2, a)) return false; + /* Always make the array part at least 1 long, so that we know key 0 + * won't be in the hash part, which simplifies things. */ + t->array_size = UPB_MAX(1, asize); + t->array_count = 0; +#if UINT32_MAX >= SIZE_MAX + if (UPB_UNLIKELY(SIZE_MAX / sizeof(upb_value) < t->array_size)) { + return false; + } +#endif + + // Allocate the array part and the presence mask array in one allocation. + size_t array_bytes = t->array_size * sizeof(upb_value); + uint32_t presence_bytes = presence_mask_arr_size(t->array_size); + uintptr_t total_bytes = array_bytes + presence_bytes; + if (UPB_UNLIKELY(total_bytes > SIZE_MAX)) { + return false; + } + void* alloc = upb_Arena_Malloc(a, total_bytes); + if (!alloc) { + return false; + } + t->array = alloc; + memset(mutable_array(t), 0xff, array_bytes); + t->presence_mask = (uint8_t*)alloc + array_bytes; + memset((uint8_t*)t->presence_mask, 0, presence_bytes); + + check(t); + return true; +} + +bool upb_inttable_init(upb_inttable* t, upb_Arena* a) { + // The init size of the table part to match that of strtable. + return upb_inttable_sizedinit(t, 0, 3, a); +} + +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a) { + if (key < t->array_size) { + UPB_ASSERT(!upb_inttable_arrhas(t, key)); + t->array_count++; + mutable_array(t)[key] = val; + ((uint8_t*)t->presence_mask)[key / 8] |= (1 << (key % 8)); + } else { + if (isfull(&t->t)) { + /* Need to resize the hash part, but we re-use the array part. */ + size_t i; + upb_table new_table; + + if (!init(&new_table, _upb_log2_table_size(&t->t) + 1, a)) { + return false; + } + + for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) { + const upb_tabent* e = &t->t.entries[i]; + insert(&new_table, intkey(e->key.num), e->key, e->val, + inthash(e->key, e->val), &inthash, &inteql); + } + + UPB_ASSERT(t->t.count == new_table.count); + + t->t = new_table; + } + upb_key tabkey = {.num = key}; + insert(&t->t, intkey(key), tabkey, val, upb_inthash(key), &inthash, + &inteql); + } + check(t); + return true; +} + +bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v) { + const upb_value* table_v = inttable_val_const(t, key); + if (!table_v) return false; + if (v) *v = *table_v; + return true; +} + +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val) { + upb_value* table_v = inttable_val(t, key); + if (!table_v) return false; + *table_v = val; + return true; +} + +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val) { + bool success; + if (key < t->array_size) { + if (upb_inttable_arrhas(t, key)) { + t->array_count--; + if (val) { + *val = t->array[key]; + } + mutable_array(t)[key] = kInttableSentinel; + ((uint8_t*)t->presence_mask)[key / 8] &= ~(1 << (key % 8)); + success = true; + } else { + success = false; + } + } else { + success = rm(&t->t, intkey(key), val, upb_inthash(key), &inteql); + } + check(t); + return success; +} + +bool upb_inttable_compact(upb_inttable* t, upb_Arena* a) { + /* A power-of-two histogram of the table keys. */ + uint32_t counts[UPB_MAXARRSIZE + 1] = {0}; + + /* The max key in each bucket. */ + uintptr_t max[UPB_MAXARRSIZE + 1] = {0}; + + { + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + while (upb_inttable_next(t, &key, &val, &iter)) { + int bucket = log2ceil(key); + max[bucket] = UPB_MAX(max[bucket], key); + counts[bucket]++; + } + } + + /* Find the largest power of two that satisfies the MIN_DENSITY + * definition (while actually having some keys). */ + uint32_t arr_count = upb_inttable_count(t); + + // Scan all buckets except capped bucket + int size_lg2 = ARRAY_SIZE(counts) - 1; + for (; size_lg2 > 0; size_lg2--) { + if (counts[size_lg2] == 0) { + /* We can halve again without losing any entries. */ + continue; + } else if (arr_count >= (1 << size_lg2) * MIN_DENSITY) { + break; + } + + arr_count -= counts[size_lg2]; + } + + UPB_ASSERT(arr_count <= upb_inttable_count(t)); + + upb_inttable new_t; + { + /* Insert all elements into new, perfectly-sized table. */ + uintptr_t arr_size = max[size_lg2] + 1; /* +1 so arr[max] will fit. */ + uint32_t hash_count = upb_inttable_count(t) - arr_count; + size_t hash_size = hash_count ? _upb_entries_needed_for(hash_count) : 0; + int hashsize_lg2 = log2ceil(hash_size); + + if (!upb_inttable_sizedinit(&new_t, arr_size, hashsize_lg2, a)) { + return false; + } + + { + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + while (upb_inttable_next(t, &key, &val, &iter)) { + upb_inttable_insert(&new_t, key, val, a); + } + } + + UPB_ASSERT(new_t.array_size == arr_size); + } + *t = new_t; + return true; +} + +void upb_inttable_clear(upb_inttable* t) { + // Clear the array part. + size_t array_bytes = t->array_size * sizeof(upb_value); + t->array_count = 0; + // Clear the array by setting all bits to 1, as UINT64_MAX is the sentinel + // value for an empty array. + memset(mutable_array(t), 0xff, array_bytes); + // Clear the presence mask array. + memset((uint8_t*)t->presence_mask, 0, presence_mask_arr_size(t->array_size)); + // Clear the table part. + size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent); + t->t.count = 0; + memset((char*)t->t.entries, 0, bytes); +} + +// Iteration. + +bool upb_inttable_next(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter) { + intptr_t i = *iter; + if ((size_t)(i + 1) <= t->array_size) { + while ((size_t)++i < t->array_size) { + const upb_value* ent = inttable_array_get(t, i); + if (ent) { + *key = i; + *val = *ent; + *iter = i; + return true; + } + } + i--; // Back up to exactly one position before the start of the table. + } + + size_t tab_idx = next(&t->t, i - t->array_size); + if (tab_idx < upb_table_size(&t->t)) { + upb_tabent* ent = &t->t.entries[tab_idx]; + *key = ent->key.num; + *val = ent->val; + *iter = tab_idx + t->array_size; + return true; + } else { + // We should set the iterator any way. When we are done, the iterator value + // is invalidated. `upb_inttable_done` will check on the iterator value to + // determine if the iteration is done. + *iter = INTPTR_MAX - 1; // To disambiguate from UPB_INTTABLE_BEGIN, to + // match the behavior of `upb_strtable_iter`. + return false; + } +} + +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter) { + intptr_t i = *iter; + if ((size_t)i < t->array_size) { + t->array_count--; + mutable_array(t)[i].val = -1; + } else { + upb_tabent* ent = &t->t.entries[i - t->array_size]; + upb_tabent* prev = NULL; + + // Linear search, not great. + upb_tabent* end = &t->t.entries[upb_table_size(&t->t)]; + for (upb_tabent* e = t->t.entries; e != end; e++) { + if (e->next == ent) { + prev = e; + break; + } + } + + if (prev) { + prev->next = ent->next; + } + + t->t.count--; + ent->key = upb_key_empty(); + ent->next = NULL; + } +} + +void upb_inttable_setentryvalue(upb_inttable* t, intptr_t iter, upb_value v) { + if ((size_t)iter < t->array_size) { + mutable_array(t)[iter] = v; + } else { + upb_tabent* ent = &t->t.entries[iter - t->array_size]; + ent->val = v; + } +} + +bool upb_inttable_done(const upb_inttable* t, intptr_t iter) { + if ((uintptr_t)iter >= t->array_size + upb_table_size(&t->t)) { + return true; + } else if ((size_t)iter < t->array_size) { + return !upb_inttable_arrhas(t, iter); + } else { + return upb_tabent_isempty(&t->t.entries[iter - t->array_size]); + } +} + +uintptr_t upb_inttable_iter_key(const upb_inttable* t, intptr_t iter) { + UPB_ASSERT(!upb_inttable_done(t, iter)); + return (size_t)iter < t->array_size + ? iter + : t->t.entries[iter - t->array_size].key.num; +} + +upb_value upb_inttable_iter_value(const upb_inttable* t, intptr_t iter) { + UPB_ASSERT(!upb_inttable_done(t, iter)); + if ((size_t)iter < t->array_size) { + return t->array[iter]; + } else { + return t->t.entries[iter - t->array_size].val; + } +} + + +#include <errno.h> +#include <float.h> +#include <inttypes.h> +#include <limits.h> +#include <math.h> +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Must be last. + +typedef struct { + const char *ptr, *end; + upb_Arena* arena; /* TODO: should we have a tmp arena for tmp data? */ + const upb_DefPool* symtab; + int depth; + int result; + upb_Status* status; + jmp_buf err; + int line; + const char* line_begin; + bool is_first; + int options; + const upb_FieldDef* debug_field; +} jsondec; + +typedef struct { + upb_MessageValue value; + bool ignore; +} upb_JsonMessageValue; + +enum { JD_OBJECT, JD_ARRAY, JD_STRING, JD_NUMBER, JD_TRUE, JD_FALSE, JD_NULL }; + +/* Forward declarations of mutually-recursive functions. */ +static void jsondec_wellknown(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); +static upb_JsonMessageValue jsondec_value(jsondec* d, const upb_FieldDef* f); +static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); +static void jsondec_object(jsondec* d, upb_Message* msg, + const upb_MessageDef* m); + +static bool jsondec_streql(upb_StringView str, const char* lit) { + return str.size == strlen(lit) && memcmp(str.data, lit, str.size) == 0; +} + +static bool jsondec_isnullvalue(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum && + strcmp(upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f)), + "google.protobuf.NullValue") == 0; +} + +static bool jsondec_isvalue(const upb_FieldDef* f) { + return (upb_FieldDef_CType(f) == kUpb_CType_Message && + upb_MessageDef_WellKnownType(upb_FieldDef_MessageSubDef(f)) == + kUpb_WellKnown_Value) || + jsondec_isnullvalue(f); +} + +static void jsondec_seterrmsg(jsondec* d, const char* msg) { + upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: %s", d->line, + (int)(d->ptr - d->line_begin), msg); +} + +UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { + jsondec_seterrmsg(d, msg); + UPB_LONGJMP(d->err, 1); +} + +UPB_PRINTF(2, 3) +UPB_NORETURN static void jsondec_errf(jsondec* d, const char* fmt, ...) { + va_list argp; + upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: ", d->line, + (int)(d->ptr - d->line_begin)); + va_start(argp, fmt); + upb_Status_VAppendErrorFormat(d->status, fmt, argp); + va_end(argp); + UPB_LONGJMP(d->err, 1); +} + +// Advances d->ptr until the next non-whitespace character or to the end of +// the buffer. +static void jsondec_consumews(jsondec* d) { + while (d->ptr != d->end) { + switch (*d->ptr) { + case '\n': + d->line++; + d->line_begin = d->ptr; + /* Fallthrough. */ + case '\r': + case '\t': + case ' ': + d->ptr++; + break; + default: + return; + } + } +} + +// Advances d->ptr until the next non-whitespace character. Postcondition that +// d->ptr is pointing at a valid non-whitespace character (will err if end of +// buffer is reached). +static void jsondec_skipws(jsondec* d) { + jsondec_consumews(d); + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } +} + +static bool jsondec_tryparsech(jsondec* d, char ch) { + if (d->ptr == d->end || *d->ptr != ch) return false; + d->ptr++; + return true; +} + +static void jsondec_parselit(jsondec* d, const char* lit) { + size_t avail = d->end - d->ptr; + size_t len = strlen(lit); + if (avail < len || memcmp(d->ptr, lit, len) != 0) { + jsondec_errf(d, "Expected: '%s'", lit); + } + d->ptr += len; +} + +static void jsondec_wsch(jsondec* d, char ch) { + jsondec_skipws(d); + if (!jsondec_tryparsech(d, ch)) { + jsondec_errf(d, "Expected: '%c'", ch); + } +} + +static void jsondec_true(jsondec* d) { jsondec_parselit(d, "true"); } +static void jsondec_false(jsondec* d) { jsondec_parselit(d, "false"); } +static void jsondec_null(jsondec* d) { jsondec_parselit(d, "null"); } + +static void jsondec_entrysep(jsondec* d) { + jsondec_skipws(d); + jsondec_parselit(d, ":"); +} + +static int jsondec_rawpeek(jsondec* d) { + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } + + switch (*d->ptr) { + case '{': + return JD_OBJECT; + case '[': + return JD_ARRAY; + case '"': + return JD_STRING; + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return JD_NUMBER; + case 't': + return JD_TRUE; + case 'f': + return JD_FALSE; + case 'n': + return JD_NULL; + default: + jsondec_errf(d, "Unexpected character: '%c'", *d->ptr); + } +} + +/* JSON object/array **********************************************************/ + +/* These are used like so: + * + * jsondec_objstart(d); + * while (jsondec_objnext(d)) { + * ... + * } + * jsondec_objend(d) */ + +static int jsondec_peek(jsondec* d) { + jsondec_skipws(d); + return jsondec_rawpeek(d); +} + +static void jsondec_push(jsondec* d) { + if (--d->depth < 0) { + jsondec_err(d, "Recursion limit exceeded"); + } + d->is_first = true; +} + +static bool jsondec_seqnext(jsondec* d, char end_ch) { + bool is_first = d->is_first; + d->is_first = false; + jsondec_skipws(d); + if (*d->ptr == end_ch) return false; + if (!is_first) jsondec_parselit(d, ","); + return true; +} + +static void jsondec_arrstart(jsondec* d) { + jsondec_push(d); + jsondec_wsch(d, '['); +} + +static void jsondec_arrend(jsondec* d) { + d->depth++; + jsondec_wsch(d, ']'); +} + +static bool jsondec_arrnext(jsondec* d) { return jsondec_seqnext(d, ']'); } + +static void jsondec_objstart(jsondec* d) { + jsondec_push(d); + jsondec_wsch(d, '{'); +} + +static void jsondec_objend(jsondec* d) { + d->depth++; + jsondec_wsch(d, '}'); +} + +static bool jsondec_objnext(jsondec* d) { + if (!jsondec_seqnext(d, '}')) return false; + if (jsondec_peek(d) != JD_STRING) { + jsondec_err(d, "Object must start with string"); + } + return true; +} + +/* JSON number ****************************************************************/ + +static bool jsondec_tryskipdigits(jsondec* d) { + const char* start = d->ptr; + + while (d->ptr < d->end) { + if (*d->ptr < '0' || *d->ptr > '9') { + break; + } + d->ptr++; + } + + return d->ptr != start; +} + +static void jsondec_skipdigits(jsondec* d) { + if (!jsondec_tryskipdigits(d)) { + jsondec_err(d, "Expected one or more digits"); + } +} + +static double jsondec_number(jsondec* d) { + const char* start = d->ptr; + + UPB_ASSERT(jsondec_rawpeek(d) == JD_NUMBER); + + /* Skip over the syntax of a number, as specified by JSON. */ + if (*d->ptr == '-') d->ptr++; + + if (jsondec_tryparsech(d, '0')) { + if (jsondec_tryskipdigits(d)) { + jsondec_err(d, "number cannot have leading zero"); + } + } else { + jsondec_skipdigits(d); + } + + if (d->ptr == d->end) goto parse; + if (jsondec_tryparsech(d, '.')) { + jsondec_skipdigits(d); + } + if (d->ptr == d->end) goto parse; + + if (*d->ptr == 'e' || *d->ptr == 'E') { + d->ptr++; + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF in number"); + } + if (*d->ptr == '+' || *d->ptr == '-') { + d->ptr++; + } + jsondec_skipdigits(d); + } + +parse: + /* Having verified the syntax of a JSON number, use strtod() to parse + * (strtod() accepts a superset of JSON syntax). */ + errno = 0; + { + // Copy the number into a null-terminated scratch buffer since strtod + // expects a null-terminated string. + char nullz[64]; + ptrdiff_t len = d->ptr - start; + if (len > (ptrdiff_t)(sizeof(nullz) - 1)) { + jsondec_err(d, "excessively long number"); + } + memcpy(nullz, start, len); + nullz[len] = '\0'; + + char* end; + double val = strtod(nullz, &end); + UPB_ASSERT(end - nullz == len); + + /* Currently the min/max-val conformance tests fail if we check this. Does + * this mean the conformance tests are wrong or strtod() is wrong, or + * something else? Investigate further. */ + /* + if (errno == ERANGE) { + jsondec_err(d, "Number out of range"); + } + */ + + if (val > DBL_MAX || val < -DBL_MAX) { + jsondec_err(d, "Number out of range"); + } + + return val; + } +} + +/* JSON string ****************************************************************/ + +static char jsondec_escape(jsondec* d) { + switch (*d->ptr++) { + case '"': + return '\"'; + case '\\': + return '\\'; + case '/': + return '/'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + default: + jsondec_err(d, "Invalid escape char"); + } +} + +static uint32_t jsondec_codepoint(jsondec* d) { + uint32_t cp = 0; + const char* end; + + if (d->end - d->ptr < 4) { + jsondec_err(d, "EOF inside string"); + } + + end = d->ptr + 4; + while (d->ptr < end) { + char ch = *d->ptr++; + if (ch >= '0' && ch <= '9') { + ch -= '0'; + } else if (ch >= 'a' && ch <= 'f') { + ch = ch - 'a' + 10; + } else if (ch >= 'A' && ch <= 'F') { + ch = ch - 'A' + 10; + } else { + jsondec_err(d, "Invalid hex digit"); + } + cp = (cp << 4) | ch; + } + + return cp; +} + +/* Parses a \uXXXX unicode escape (possibly a surrogate pair). */ +static size_t jsondec_unicode(jsondec* d, char* out) { + uint32_t cp = jsondec_codepoint(d); + if (upb_Unicode_IsHigh(cp)) { + /* Surrogate pair: two 16-bit codepoints become a 32-bit codepoint. */ + jsondec_parselit(d, "\\u"); + uint32_t low = jsondec_codepoint(d); + if (!upb_Unicode_IsLow(low)) jsondec_err(d, "Invalid low surrogate"); + cp = upb_Unicode_FromPair(cp, low); + } else if (upb_Unicode_IsLow(cp)) { + jsondec_err(d, "Unpaired low surrogate"); + } + + /* Write to UTF-8 */ + int bytes = upb_Unicode_ToUTF8(cp, out); + if (bytes == 0) jsondec_err(d, "Invalid codepoint"); + return bytes; +} + +static void jsondec_resize(jsondec* d, char** buf, char** end, char** buf_end) { + size_t oldsize = *buf_end - *buf; + size_t len = *end - *buf; + size_t size = UPB_MAX(8, 2 * oldsize); + + *buf = upb_Arena_Realloc(d->arena, *buf, len, size); + if (!*buf) jsondec_err(d, "Out of memory"); + + *end = *buf + len; + *buf_end = *buf + size; +} + +static upb_StringView jsondec_string(jsondec* d) { + char* buf = NULL; + char* end = NULL; + char* buf_end = NULL; + + jsondec_skipws(d); + + if (*d->ptr++ != '"') { + jsondec_err(d, "Expected string"); + } + + while (d->ptr < d->end) { + char ch = *d->ptr++; + + if (end == buf_end) { + jsondec_resize(d, &buf, &end, &buf_end); + } + + switch (ch) { + case '"': { + upb_StringView ret; + ret.data = buf; + ret.size = end - buf; + *end = '\0'; /* Needed for possible strtod(). */ + return ret; + } + case '\\': + if (d->ptr == d->end) goto eof; + if (*d->ptr == 'u') { + d->ptr++; + if (buf_end - end < 4) { + /* Allow space for maximum-sized codepoint (4 bytes). */ + jsondec_resize(d, &buf, &end, &buf_end); + } + end += jsondec_unicode(d, end); + } else { + *end++ = jsondec_escape(d); + } + break; + default: + if ((unsigned char)ch < 0x20) { + jsondec_err(d, "Invalid char in JSON string"); + } + *end++ = ch; + break; + } + } + +eof: + jsondec_err(d, "EOF inside string"); +} + +static void jsondec_skipval(jsondec* d) { + switch (jsondec_peek(d)) { + case JD_OBJECT: + jsondec_objstart(d); + while (jsondec_objnext(d)) { + jsondec_string(d); + jsondec_entrysep(d); + jsondec_skipval(d); + } + jsondec_objend(d); + break; + case JD_ARRAY: + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + jsondec_skipval(d); + } + jsondec_arrend(d); + break; + case JD_TRUE: + jsondec_true(d); + break; + case JD_FALSE: + jsondec_false(d); + break; + case JD_NULL: + jsondec_null(d); + break; + case JD_STRING: + jsondec_string(d); + break; + case JD_NUMBER: + jsondec_number(d); + break; + } +} + +/* Base64 decoding for bytes fields. ******************************************/ + +static unsigned int jsondec_base64_tablelookup(const char ch) { + /* Table includes the normal base64 chars plus the URL-safe variant. */ + const signed char table[256] = { + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, 62 /*+*/, -1, 62 /*-*/, -1, 63 /*/ */, 52 /*0*/, + 53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/, 59 /*7*/, + 60 /*8*/, 61 /*9*/, -1, -1, -1, -1, -1, + -1, -1, 0 /*A*/, 1 /*B*/, 2 /*C*/, 3 /*D*/, 4 /*E*/, + 5 /*F*/, 6 /*G*/, 07 /*H*/, 8 /*I*/, 9 /*J*/, 10 /*K*/, 11 /*L*/, + 12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/, 18 /*S*/, + 19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/, 25 /*Z*/, + -1, -1, -1, -1, 63 /*_*/, -1, 26 /*a*/, + 27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/, 33 /*h*/, + 34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/, 40 /*o*/, + 41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/, 47 /*v*/, + 48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1}; + + /* Sign-extend return value so high bit will be set on any unexpected char. */ + return table[(unsigned)ch]; +} + +static char* jsondec_partialbase64(jsondec* d, const char* ptr, const char* end, + char* out) { + int32_t val = -1; + + switch (end - ptr) { + case 2: + val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12; + out[0] = val >> 16; + out += 1; + break; + case 3: + val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12 | + jsondec_base64_tablelookup(ptr[2]) << 6; + out[0] = val >> 16; + out[1] = (val >> 8) & 0xff; + out += 2; + break; + } + + if (val < 0) { + jsondec_err(d, "Corrupt base64"); + } + + return out; +} + +static size_t jsondec_base64(jsondec* d, upb_StringView str) { + /* We decode in place. This is safe because this is a new buffer (not + * aliasing the input) and because base64 decoding shrinks 4 bytes into 3. */ + char* out = (char*)str.data; + const char* ptr = str.data; + const char* end = ptr + str.size; + const char* end4 = ptr + (str.size & -4); /* Round down to multiple of 4. */ + + for (; ptr < end4; ptr += 4, out += 3) { + int val = jsondec_base64_tablelookup(ptr[0]) << 18 | + jsondec_base64_tablelookup(ptr[1]) << 12 | + jsondec_base64_tablelookup(ptr[2]) << 6 | + jsondec_base64_tablelookup(ptr[3]) << 0; + + if (val < 0) { + /* Junk chars or padding. Remove trailing padding, if any. */ + if (end - ptr == 4 && ptr[3] == '=') { + if (ptr[2] == '=') { + end -= 2; + } else { + end -= 1; + } + } + break; + } + + out[0] = val >> 16; + out[1] = (val >> 8) & 0xff; + out[2] = val & 0xff; + } + + if (ptr < end) { + /* Process remaining chars. We do not require padding. */ + out = jsondec_partialbase64(d, ptr, end, out); + } + + return out - str.data; +} + +/* Low-level integer parsing **************************************************/ + +static const char* jsondec_buftouint64(jsondec* d, const char* ptr, + const char* end, uint64_t* val) { + const char* out = upb_BufToUint64(ptr, end, val); + if (!out) jsondec_err(d, "Integer overflow"); + return out; +} + +static const char* jsondec_buftoint64(jsondec* d, const char* ptr, + const char* end, int64_t* val, + bool* is_neg) { + const char* out = upb_BufToInt64(ptr, end, val, is_neg); + if (!out) jsondec_err(d, "Integer overflow"); + return out; +} + +static uint64_t jsondec_strtouint64(jsondec* d, upb_StringView str) { + const char* end = str.data + str.size; + uint64_t ret; + if (jsondec_buftouint64(d, str.data, end, &ret) != end) { + jsondec_err(d, "Non-number characters in quoted integer"); + } + return ret; +} + +static int64_t jsondec_strtoint64(jsondec* d, upb_StringView str) { + const char* end = str.data + str.size; + int64_t ret; + if (jsondec_buftoint64(d, str.data, end, &ret, NULL) != end) { + jsondec_err(d, "Non-number characters in quoted integer"); + } + return ret; +} + +static void jsondec_checkempty(jsondec* d, upb_StringView str, + const upb_FieldDef* f) { + if (str.size != 0) return; + d->result = kUpb_JsonDecodeResult_Error; + upb_Status_SetErrorFormat(d->status, + "Empty string is not a valid number (field: %s). " + "This will be an error in a future version.", + upb_FieldDef_FullName(f)); +} + +/* Primitive value types ******************************************************/ + +/* Parse INT32 or INT64 value. */ +static upb_MessageValue jsondec_int(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: { + double dbl = jsondec_number(d); + if (dbl > 9223372036854774784.0 || dbl < -9223372036854775808.0) { + jsondec_err(d, "JSON number is out of range."); + } + val.int64_val = dbl; /* must be guarded, overflow here is UB */ + if (val.int64_val != dbl) { + jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl, + val.int64_val); + } + break; + } + case JD_STRING: { + upb_StringView str = jsondec_string(d); + jsondec_checkempty(d, str, f); + val.int64_val = jsondec_strtoint64(d, str); + break; + } + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_FieldDef_CType(f) == kUpb_CType_Int32 || + upb_FieldDef_CType(f) == kUpb_CType_Enum) { + if (val.int64_val > INT32_MAX || val.int64_val < INT32_MIN) { + jsondec_err(d, "Integer out of range."); + } + val.int32_val = (int32_t)val.int64_val; + } + + return val; +} + +/* Parse UINT32 or UINT64 value. */ +static upb_MessageValue jsondec_uint(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: { + double dbl = jsondec_number(d); + if (dbl > 18446744073709549568.0 || dbl < 0) { + jsondec_err(d, "JSON number is out of range."); + } + val.uint64_val = dbl; /* must be guarded, overflow here is UB */ + if (val.uint64_val != dbl) { + jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl, + val.uint64_val); + } + break; + } + case JD_STRING: { + upb_StringView str = jsondec_string(d); + jsondec_checkempty(d, str, f); + val.uint64_val = jsondec_strtouint64(d, str); + break; + } + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_FieldDef_CType(f) == kUpb_CType_UInt32) { + if (val.uint64_val > UINT32_MAX) { + jsondec_err(d, "Integer out of range."); + } + val.uint32_val = (uint32_t)val.uint64_val; + } + + return val; +} + +/* Parse DOUBLE or FLOAT value. */ +static upb_MessageValue jsondec_double(jsondec* d, const upb_FieldDef* f) { + upb_StringView str; + upb_MessageValue val; + + switch (jsondec_peek(d)) { + case JD_NUMBER: + val.double_val = jsondec_number(d); + break; + case JD_STRING: + str = jsondec_string(d); + if (str.size == 0) { + jsondec_checkempty(d, str, f); + val.double_val = 0.0; + } else if (jsondec_streql(str, "NaN")) { + val.double_val = NAN; + } else if (jsondec_streql(str, "Infinity")) { + val.double_val = INFINITY; + } else if (jsondec_streql(str, "-Infinity")) { + val.double_val = -INFINITY; + } else { + char* end; + val.double_val = strtod(str.data, &end); + if (end != str.data + str.size) { + d->result = kUpb_JsonDecodeResult_Error; + upb_Status_SetErrorFormat( + d->status, + "Non-number characters in quoted number (field: %s). " + "This will be an error in a future version.", + upb_FieldDef_FullName(f)); + } + } + break; + default: + jsondec_err(d, "Expected number or string"); + } + + if (upb_FieldDef_CType(f) == kUpb_CType_Float) { + float f = val.double_val; + if (val.double_val != INFINITY && val.double_val != -INFINITY) { + if (f == INFINITY || f == -INFINITY) jsondec_err(d, "Float out of range"); + } + val.float_val = f; + } + + return val; +} + +/* Parse STRING or BYTES value. */ +static upb_MessageValue jsondec_strfield(jsondec* d, const upb_FieldDef* f) { + upb_MessageValue val; + val.str_val = jsondec_string(d); + if (upb_FieldDef_CType(f) == kUpb_CType_Bytes) { + val.str_val.size = jsondec_base64(d, val.str_val); + } + return val; +} + +static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) { + switch (jsondec_peek(d)) { + case JD_STRING: { + upb_StringView str = jsondec_string(d); + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size); + upb_JsonMessageValue val = {.ignore = false}; + if (ev) { + val.value.int32_val = upb_EnumValueDef_Number(ev); + } else { + if (d->options & upb_JsonDecode_IgnoreUnknown) { + val.ignore = true; + } else { + jsondec_errf(d, "Unknown enumerator: '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(str)); + } + } + return val; + } + case JD_NULL: { + if (jsondec_isnullvalue(f)) { + upb_JsonMessageValue val = {.ignore = false}; + jsondec_null(d); + val.value.int32_val = 0; + return val; + } + } + /* Fallthrough. */ + default: + return (upb_JsonMessageValue){.value = jsondec_int(d, f), + .ignore = false}; + } +} + +static upb_MessageValue jsondec_bool(jsondec* d, const upb_FieldDef* f) { + bool is_map_key = upb_FieldDef_Number(f) == 1 && + upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f)); + upb_MessageValue val; + + if (is_map_key) { + upb_StringView str = jsondec_string(d); + if (jsondec_streql(str, "true")) { + val.bool_val = true; + } else if (jsondec_streql(str, "false")) { + val.bool_val = false; + } else { + jsondec_err(d, "Invalid boolean map key"); + } + } else { + switch (jsondec_peek(d)) { + case JD_TRUE: + val.bool_val = true; + jsondec_true(d); + break; + case JD_FALSE: + val.bool_val = false; + jsondec_false(d); + break; + default: + jsondec_err(d, "Expected true or false"); + } + } + + return val; +} + +/* Composite types (array/message/map) ****************************************/ + +static void jsondec_array(jsondec* d, upb_Message* msg, const upb_FieldDef* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Array* arr = upb_Message_Mutable(msg, f, d->arena).array; + + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + upb_JsonMessageValue elem = jsondec_value(d, f); + if (!elem.ignore) { + upb_Array_Append(arr, elem.value, d->arena); + } + } + jsondec_arrend(d); +} + +static void jsondec_map(jsondec* d, upb_Message* msg, const upb_FieldDef* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Map* map = upb_Message_Mutable(msg, f, d->arena).map; + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2); + + jsondec_objstart(d); + while (jsondec_objnext(d)) { + upb_JsonMessageValue key, val; + key = jsondec_value(d, key_f); + UPB_ASSUME(!key.ignore); // Map key cannot be enum. + jsondec_entrysep(d); + val = jsondec_value(d, val_f); + if (!val.ignore) { + upb_Map_Set(map, key.value, val.value, d->arena); + } + } + jsondec_objend(d); +} + +static void jsondec_tomsg(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (upb_MessageDef_WellKnownType(m) == kUpb_WellKnown_Unspecified) { + jsondec_object(d, msg, m); + } else { + jsondec_wellknown(d, msg, m); + } +} + +static upb_MessageValue jsondec_msg(jsondec* d, const upb_FieldDef* f) { + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); + upb_Message* msg = upb_Message_New(layout, d->arena); + upb_MessageValue val; + + jsondec_tomsg(d, msg, m); + val.msg_val = msg; + return val; +} + +static void jsondec_field(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_StringView name; + const upb_FieldDef* f; + const upb_FieldDef* preserved; + + name = jsondec_string(d); + jsondec_entrysep(d); + + if (name.size >= 2 && name.data[0] == '[' && + name.data[name.size - 1] == ']') { + f = upb_DefPool_FindExtensionByNameWithSize(d->symtab, name.data + 1, + name.size - 2); + if (f && upb_FieldDef_ContainingType(f) != m) { + jsondec_errf( + d, "Extension %s extends message %s, but was seen in message %s", + upb_FieldDef_FullName(f), + upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)), + upb_MessageDef_FullName(m)); + } + } else { + f = upb_MessageDef_FindByJsonNameWithSize(m, name.data, name.size); + } + + if (!f) { + if ((d->options & upb_JsonDecode_IgnoreUnknown) == 0) { + jsondec_errf(d, "No such field: " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(name)); + } + jsondec_skipval(d); + return; + } + + if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) { + /* JSON "null" indicates a default value, so no need to set anything. */ + jsondec_null(d); + return; + } + + if (upb_FieldDef_RealContainingOneof(f) && + upb_Message_WhichOneofByDef(msg, upb_FieldDef_ContainingOneof(f))) { + jsondec_err(d, "More than one field for this oneof."); + } + + preserved = d->debug_field; + d->debug_field = f; + + if (upb_FieldDef_IsMap(f)) { + jsondec_map(d, msg, f); + } else if (upb_FieldDef_IsRepeated(f)) { + jsondec_array(d, msg, f); + } else if (upb_FieldDef_IsSubMessage(f)) { + upb_Message* submsg = upb_Message_Mutable(msg, f, d->arena).msg; + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f); + jsondec_tomsg(d, submsg, subm); + } else { + upb_JsonMessageValue val = jsondec_value(d, f); + if (!val.ignore) { + upb_Message_SetFieldByDef(msg, f, val.value, d->arena); + } + } + + d->debug_field = preserved; +} + +static void jsondec_object(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + jsondec_objstart(d); + while (jsondec_objnext(d)) { + jsondec_field(d, msg, m); + } + jsondec_objend(d); +} + +static upb_MessageValue jsondec_nonenum(jsondec* d, const upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return jsondec_bool(d, f); + case kUpb_CType_Float: + case kUpb_CType_Double: + return jsondec_double(d, f); + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + return jsondec_uint(d, f); + case kUpb_CType_Int32: + case kUpb_CType_Int64: + return jsondec_int(d, f); + case kUpb_CType_String: + case kUpb_CType_Bytes: + return jsondec_strfield(d, f); + case kUpb_CType_Message: + return jsondec_msg(d, f); + case kUpb_CType_Enum: + default: + UPB_UNREACHABLE(); + } +} + +static upb_JsonMessageValue jsondec_value(jsondec* d, const upb_FieldDef* f) { + if (upb_FieldDef_CType(f) == kUpb_CType_Enum) { + return jsondec_enum(d, f); + } else { + return (upb_JsonMessageValue){.value = jsondec_nonenum(d, f), + .ignore = false}; + } +} + +/* Well-known types ***********************************************************/ + +static int jsondec_tsdigits(jsondec* d, const char** ptr, size_t digits, + const char* after) { + uint64_t val; + const char* p = *ptr; + const char* end = p + digits; + size_t after_len = after ? strlen(after) : 0; + + UPB_ASSERT(digits <= 9); /* int can't overflow. */ + + if (jsondec_buftouint64(d, p, end, &val) != end || + (after_len && memcmp(end, after, after_len) != 0)) { + jsondec_err(d, "Malformed timestamp"); + } + + UPB_ASSERT(val < INT_MAX); + + *ptr = end + after_len; + return (int)val; +} + +static int jsondec_nanos(jsondec* d, const char** ptr, const char* end) { + uint64_t nanos = 0; + const char* p = *ptr; + + if (p != end && *p == '.') { + const char* nano_end = jsondec_buftouint64(d, p + 1, end, &nanos); + int digits = (int)(nano_end - p - 1); + int exp_lg10 = 9 - digits; + if (digits > 9) { + jsondec_err(d, "Too many digits for partial seconds"); + } + while (exp_lg10--) nanos *= 10; + *ptr = nano_end; + } + + UPB_ASSERT(nanos < INT_MAX); + + return (int)nanos; +} + +/* jsondec_epochdays(1970, 1, 1) == 1970-01-01 == 0. */ +int jsondec_epochdays(int y, int m, int d) { + const uint32_t year_base = 4800; /* Before min year, multiple of 400. */ + const uint32_t m_adj = m - 3; /* March-based month. */ + const uint32_t carry = m_adj > (uint32_t)m ? 1 : 0; + const uint32_t adjust = carry ? 12 : 0; + const uint32_t y_adj = y + year_base - carry; + const uint32_t month_days = ((m_adj + adjust) * 62719 + 769) / 2048; + const uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400; + return y_adj * 365 + leap_days + month_days + (d - 1) - 2472632; +} + +static int64_t jsondec_unixtime(int y, int m, int d, int h, int min, int s) { + return (int64_t)jsondec_epochdays(y, m, d) * 86400 + h * 3600 + min * 60 + s; +} + +static void jsondec_timestamp(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_MessageValue seconds; + upb_MessageValue nanos; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + + if (str.size < 20) goto malformed; + + { + /* 1972-01-01T01:00:00 */ + int year = jsondec_tsdigits(d, &ptr, 4, "-"); + int mon = jsondec_tsdigits(d, &ptr, 2, "-"); + int day = jsondec_tsdigits(d, &ptr, 2, "T"); + int hour = jsondec_tsdigits(d, &ptr, 2, ":"); + int min = jsondec_tsdigits(d, &ptr, 2, ":"); + int sec = jsondec_tsdigits(d, &ptr, 2, NULL); + + seconds.int64_val = jsondec_unixtime(year, mon, day, hour, min, sec); + } + + nanos.int32_val = jsondec_nanos(d, &ptr, end); + + { + /* [+-]08:00 or Z */ + int ofs_hour = 0; + int ofs_min = 0; + bool neg = false; + + if (ptr == end) goto malformed; + + switch (*ptr++) { + case '-': + neg = true; + /* fallthrough */ + case '+': + if ((end - ptr) != 5) goto malformed; + ofs_hour = jsondec_tsdigits(d, &ptr, 2, ":"); + ofs_min = jsondec_tsdigits(d, &ptr, 2, NULL); + ofs_min = ((ofs_hour * 60) + ofs_min) * 60; + seconds.int64_val += (neg ? ofs_min : -ofs_min); + break; + case 'Z': + if (ptr != end) goto malformed; + break; + default: + goto malformed; + } + } + + if (seconds.int64_val < -62135596800) { + jsondec_err(d, "Timestamp out of range"); + } + + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 1), + seconds, d->arena); + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 2), nanos, + d->arena); + return; + +malformed: + jsondec_err(d, "Malformed timestamp"); +} + +static void jsondec_duration(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_MessageValue seconds; + upb_MessageValue nanos; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + const int64_t max = (uint64_t)3652500 * 86400; + bool neg = false; + + /* "3.000000001s", "3s", etc. */ + ptr = jsondec_buftoint64(d, ptr, end, &seconds.int64_val, &neg); + nanos.int32_val = jsondec_nanos(d, &ptr, end); + + if (end - ptr != 1 || *ptr != 's') { + jsondec_err(d, "Malformed duration"); + } + + if (seconds.int64_val < -max || seconds.int64_val > max) { + jsondec_err(d, "Duration out of range"); + } + + if (neg) { + nanos.int32_val = -nanos.int32_val; + } + + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 1), + seconds, d->arena); + upb_Message_SetFieldByDef(msg, upb_MessageDef_FindFieldByNumber(m, 2), nanos, + d->arena); +} + +static void jsondec_listvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(values_f); + const upb_MiniTable* value_layout = upb_MessageDef_MiniTable(value_m); + upb_Array* values = upb_Message_Mutable(msg, values_f, d->arena).array; + + jsondec_arrstart(d); + while (jsondec_arrnext(d)) { + upb_Message* value_msg = upb_Message_New(value_layout, d->arena); + upb_MessageValue value; + value.msg_val = value_msg; + upb_Array_Append(values, value, d->arena); + jsondec_wellknownvalue(d, value_msg, value_m); + } + jsondec_arrend(d); +} + +static void jsondec_struct(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + const upb_MessageDef* value_m = upb_FieldDef_MessageSubDef(value_f); + const upb_MiniTable* value_layout = upb_MessageDef_MiniTable(value_m); + upb_Map* fields = upb_Message_Mutable(msg, fields_f, d->arena).map; + + jsondec_objstart(d); + while (jsondec_objnext(d)) { + upb_MessageValue key, value; + upb_Message* value_msg = upb_Message_New(value_layout, d->arena); + key.str_val = jsondec_string(d); + value.msg_val = value_msg; + upb_Map_Set(fields, key, value, d->arena); + jsondec_entrysep(d); + jsondec_wellknownvalue(d, value_msg, value_m); + } + jsondec_objend(d); +} + +static void jsondec_wellknownvalue(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_MessageValue val; + const upb_FieldDef* f; + upb_Message* submsg; + + switch (jsondec_peek(d)) { + case JD_NUMBER: + /* double number_value = 2; */ + f = upb_MessageDef_FindFieldByNumber(m, 2); + val.double_val = jsondec_number(d); + break; + case JD_STRING: + /* string string_value = 3; */ + f = upb_MessageDef_FindFieldByNumber(m, 3); + val.str_val = jsondec_string(d); + break; + case JD_FALSE: + /* bool bool_value = 4; */ + f = upb_MessageDef_FindFieldByNumber(m, 4); + val.bool_val = false; + jsondec_false(d); + break; + case JD_TRUE: + /* bool bool_value = 4; */ + f = upb_MessageDef_FindFieldByNumber(m, 4); + val.bool_val = true; + jsondec_true(d); + break; + case JD_NULL: + /* NullValue null_value = 1; */ + f = upb_MessageDef_FindFieldByNumber(m, 1); + val.int32_val = 0; + jsondec_null(d); + break; + /* Note: these cases return, because upb_Message_Mutable() is enough. */ + case JD_OBJECT: + /* Struct struct_value = 5; */ + f = upb_MessageDef_FindFieldByNumber(m, 5); + submsg = upb_Message_Mutable(msg, f, d->arena).msg; + jsondec_struct(d, submsg, upb_FieldDef_MessageSubDef(f)); + return; + case JD_ARRAY: + /* ListValue list_value = 6; */ + f = upb_MessageDef_FindFieldByNumber(m, 6); + submsg = upb_Message_Mutable(msg, f, d->arena).msg; + jsondec_listvalue(d, submsg, upb_FieldDef_MessageSubDef(f)); + return; + default: + UPB_UNREACHABLE(); + } + + upb_Message_SetFieldByDef(msg, f, val, d->arena); +} + +static upb_StringView jsondec_mask(jsondec* d, const char* buf, + const char* end) { + /* FieldMask fields grow due to inserted '_' characters, so we can't do the + * transform in place. */ + const char* ptr = buf; + upb_StringView ret; + char* out; + + ret.size = end - ptr; + while (ptr < end) { + ret.size += (*ptr >= 'A' && *ptr <= 'Z'); + ptr++; + } + + out = upb_Arena_Malloc(d->arena, ret.size); + ptr = buf; + ret.data = out; + + while (ptr < end) { + char ch = *ptr++; + if (ch >= 'A' && ch <= 'Z') { + *out++ = '_'; + *out++ = ch + 32; + } else if (ch == '_') { + jsondec_err(d, "field mask may not contain '_'"); + } else { + *out++ = ch; + } + } + + return ret; +} + +static void jsondec_fieldmask(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + /* repeated string paths = 1; */ + const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_Array* arr = upb_Message_Mutable(msg, paths_f, d->arena).array; + upb_StringView str = jsondec_string(d); + const char* ptr = str.data; + const char* end = ptr + str.size; + upb_MessageValue val; + + while (ptr < end) { + const char* elem_end = memchr(ptr, ',', end - ptr); + if (elem_end) { + val.str_val = jsondec_mask(d, ptr, elem_end); + ptr = elem_end + 1; + } else { + val.str_val = jsondec_mask(d, ptr, end); + ptr = end; + } + upb_Array_Append(arr, val, d->arena); + } +} + +static void jsondec_anyfield(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (upb_MessageDef_WellKnownType(m) == kUpb_WellKnown_Unspecified) { + /* For regular types: {"@type": "[user type]", "f1": <V1>, "f2": <V2>} + * where f1, f2, etc. are the normal fields of this type. */ + jsondec_field(d, msg, m); + } else { + /* For well-known types: {"@type": "[well-known type]", "value": <X>} + * where <X> is whatever encoding the WKT normally uses. */ + upb_StringView str = jsondec_string(d); + jsondec_entrysep(d); + if (!jsondec_streql(str, "value")) { + jsondec_err(d, "Key for well-known type must be 'value'"); + } + jsondec_wellknown(d, msg, m); + } +} + +static const upb_MessageDef* jsondec_typeurl(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* type_m; + upb_StringView type_url = jsondec_string(d); + const char* end = type_url.data + type_url.size; + const char* ptr = end; + upb_MessageValue val; + + val.str_val = type_url; + upb_Message_SetFieldByDef(msg, type_url_f, val, d->arena); + + /* Find message name after the last '/' */ + while (ptr > type_url.data && *--ptr != '/') { + } + + if (ptr == type_url.data || ptr == end) { + jsondec_err(d, "Type url must have at least one '/' and non-empty host"); + } + + ptr++; + type_m = upb_DefPool_FindMessageByNameWithSize(d->symtab, ptr, end - ptr); + + if (!type_m) { + jsondec_err(d, "Type was not found"); + } + + return type_m; +} + +static void jsondec_any(jsondec* d, upb_Message* msg, const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + /* string type_url = 1; + * bytes value = 2; */ + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2); + upb_Message* any_msg; + const upb_MessageDef* any_m = NULL; + const char* pre_type_data = NULL; + const char* pre_type_end = NULL; + upb_MessageValue encoded; + + jsondec_objstart(d); + + /* Scan looking for "@type", which is not necessarily first. */ + while (!any_m && jsondec_objnext(d)) { + const char* start = d->ptr; + upb_StringView name = jsondec_string(d); + jsondec_entrysep(d); + if (jsondec_streql(name, "@type")) { + any_m = jsondec_typeurl(d, msg, m); + if (pre_type_data) { + pre_type_end = start; + while (*pre_type_end != ',') pre_type_end--; + } + } else { + if (!pre_type_data) pre_type_data = start; + jsondec_skipval(d); + } + } + + if (!any_m) { + jsondec_err(d, "Any object didn't contain a '@type' field"); + } + + const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); + any_msg = upb_Message_New(any_layout, d->arena); + + if (pre_type_data) { + size_t len = pre_type_end - pre_type_data + 1; + char* tmp = upb_Arena_Malloc(d->arena, len); + const char* saved_ptr = d->ptr; + const char* saved_end = d->end; + memcpy(tmp, pre_type_data, len - 1); + tmp[len - 1] = '}'; + d->ptr = tmp; + d->end = tmp + len; + d->is_first = true; + while (jsondec_objnext(d)) { + jsondec_anyfield(d, any_msg, any_m); + } + d->ptr = saved_ptr; + d->end = saved_end; + } + + while (jsondec_objnext(d)) { + jsondec_anyfield(d, any_msg, any_m); + } + + jsondec_objend(d); + + upb_EncodeStatus status = + upb_Encode(any_msg, upb_MessageDef_MiniTable(any_m), 0, d->arena, + (char**)&encoded.str_val.data, &encoded.str_val.size); + // TODO: We should fail gracefully here on a bad return status. + UPB_ASSERT(status == kUpb_EncodeStatus_Ok); + upb_Message_SetFieldByDef(msg, value_f, encoded, d->arena); +} + +static void jsondec_wrapper(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_JsonMessageValue val = jsondec_value(d, value_f); + UPB_ASSUME(val.ignore == false); // Wrapper cannot be an enum. + upb_Message_SetFieldByDef(msg, value_f, val.value, d->arena); +} + +static void jsondec_wellknown(jsondec* d, upb_Message* msg, + const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Any: + jsondec_any(d, msg, m); + break; + case kUpb_WellKnown_FieldMask: + jsondec_fieldmask(d, msg, m); + break; + case kUpb_WellKnown_Duration: + jsondec_duration(d, msg, m); + break; + case kUpb_WellKnown_Timestamp: + jsondec_timestamp(d, msg, m); + break; + case kUpb_WellKnown_Value: + jsondec_wellknownvalue(d, msg, m); + break; + case kUpb_WellKnown_ListValue: + jsondec_listvalue(d, msg, m); + break; + case kUpb_WellKnown_Struct: + jsondec_struct(d, msg, m); + break; + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + jsondec_wrapper(d, msg, m); + break; + default: + UPB_UNREACHABLE(); + } +} + +static int upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg, + const upb_MessageDef* const m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (UPB_SETJMP(d->err)) return kUpb_JsonDecodeResult_Error; + + jsondec_tomsg(d, msg, m); + + // Consume any trailing whitespace before checking if we read the entire + // input. + jsondec_consumews(d); + + if (d->ptr == d->end) { + return d->result; + } else { + jsondec_seterrmsg(d, "unexpected trailing characters"); + return kUpb_JsonDecodeResult_Error; + } +} + +int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size, + upb_Message* msg, + const upb_MessageDef* m, + const upb_DefPool* symtab, + int options, upb_Arena* arena, + upb_Status* status) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + jsondec d; + + if (size == 0) return true; + + d.ptr = buf; + d.end = buf + size; + d.arena = arena; + d.symtab = symtab; + d.status = status; + d.options = options; + d.depth = 64; + d.result = kUpb_JsonDecodeResult_Ok; + d.line = 1; + d.line_begin = d.ptr; + d.debug_field = NULL; + d.is_first = false; + + return upb_JsonDecoder_Decode(&d, msg, m); +} + + +#include <ctype.h> +#include <float.h> +#include <inttypes.h> +#include <math.h> +#include <stdarg.h> +#include <string.h> + + +// Must be last. + +typedef struct { + char *buf, *ptr, *end; + size_t overflow; + int indent_depth; + int options; + const upb_DefPool* ext_pool; + jmp_buf err; + upb_Status* status; + upb_Arena* arena; +} jsonenc; + +static void jsonenc_msg(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); +static void jsonenc_scalar(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f); +static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); +static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m, bool first); +static void jsonenc_value(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m); + +UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) { + upb_Status_SetErrorMessage(e->status, msg); + UPB_LONGJMP(e->err, 1); +} + +UPB_PRINTF(2, 3) +UPB_NORETURN static void jsonenc_errf(jsonenc* e, const char* fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_Status_VSetErrorFormat(e->status, fmt, argp); + va_end(argp); + UPB_LONGJMP(e->err, 1); +} + +static upb_Arena* jsonenc_arena(jsonenc* e) { + /* Create lazily, since it's only needed for Any */ + if (!e->arena) { + e->arena = upb_Arena_New(); + } + return e->arena; +} + +static void jsonenc_putbytes(jsonenc* e, const void* data, size_t len) { + size_t have = e->end - e->ptr; + if (UPB_LIKELY(have >= len)) { + memcpy(e->ptr, data, len); + e->ptr += len; + } else { + if (have) { + memcpy(e->ptr, data, have); + e->ptr += have; + } + e->overflow += (len - have); + } +} + +static void jsonenc_putstr(jsonenc* e, const char* str) { + jsonenc_putbytes(e, str, strlen(str)); +} + +UPB_PRINTF(2, 3) +static void jsonenc_printf(jsonenc* e, const char* fmt, ...) { + size_t n; + size_t have = e->end - e->ptr; + va_list args; + + va_start(args, fmt); + n = _upb_vsnprintf(e->ptr, have, fmt, args); + va_end(args); + + if (UPB_LIKELY(have > n)) { + e->ptr += n; + } else { + e->ptr = UPB_PTRADD(e->ptr, have); + e->overflow += (n - have); + } +} + +static void jsonenc_nanos(jsonenc* e, int32_t nanos) { + int digits = 9; + + if (nanos == 0) return; + if (nanos < 0 || nanos >= 1000000000) { + jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos"); + } + + while (nanos % 1000 == 0) { + nanos /= 1000; + digits -= 3; + } + + jsonenc_printf(e, ".%.*" PRId32, digits, nanos); +} + +static void jsonenc_timestamp(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2); + int64_t seconds = upb_Message_GetFieldByDef(msg, seconds_f).int64_val; + int32_t nanos = upb_Message_GetFieldByDef(msg, nanos_f).int32_val; + int L, N, I, J, K, hour, min, sec; + + if (seconds < -62135596800) { + jsonenc_err(e, + "error formatting timestamp as JSON: minimum acceptable value " + "is 0001-01-01T00:00:00Z"); + } else if (seconds > 253402300799) { + jsonenc_err(e, + "error formatting timestamp as JSON: maximum acceptable value " + "is 9999-12-31T23:59:59Z"); + } + + /* Julian Day -> Y/M/D, Algorithm from: + * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for + * Processing Calendar Dates," Communications of the Association of + * Computing Machines, vol. 11 (1968), p. 657. */ + seconds += 62135596800; // Ensure seconds is positive. + L = (int)(seconds / 86400) - 719162 + 68569 + 2440588; + N = 4 * L / 146097; + L = L - (146097 * N + 3) / 4; + I = 4000 * (L + 1) / 1461001; + L = L - 1461 * I / 4 + 31; + J = 80 * L / 2447; + K = L - 2447 * J / 80; + L = J / 11; + J = J + 2 - 12 * L; + I = 100 * (N - 49) + I + L; + + sec = seconds % 60; + min = (seconds / 60) % 60; + hour = (seconds / 3600) % 24; + + jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec); + jsonenc_nanos(e, nanos); + jsonenc_putstr(e, "Z\""); +} + +static void jsonenc_duration(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2); + int64_t seconds = upb_Message_GetFieldByDef(msg, seconds_f).int64_val; + int32_t nanos = upb_Message_GetFieldByDef(msg, nanos_f).int32_val; + bool negative = false; + + if (seconds > 315576000000 || seconds < -315576000000 || + (seconds != 0 && nanos != 0 && (seconds < 0) != (nanos < 0))) { + jsonenc_err(e, "bad duration"); + } + + if (seconds < 0) { + negative = true; + seconds = -seconds; + } + if (nanos < 0) { + negative = true; + nanos = -nanos; + } + + jsonenc_putstr(e, "\""); + if (negative) { + jsonenc_putstr(e, "-"); + } + jsonenc_printf(e, "%" PRId64, seconds); + jsonenc_nanos(e, nanos); + jsonenc_putstr(e, "s\""); +} + +static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) { + const upb_EnumDef* e_def = upb_FieldDef_EnumSubDef(f); + + if (strcmp(upb_EnumDef_FullName(e_def), "google.protobuf.NullValue") == 0) { + jsonenc_putstr(e, "null"); + } else { + const upb_EnumValueDef* ev = + (e->options & upb_JsonEncode_FormatEnumsAsIntegers) + ? NULL + : upb_EnumDef_FindValueByNumber(e_def, val); + + if (ev) { + jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev)); + } else { + jsonenc_printf(e, "%" PRId32, val); + } + } +} + +static void jsonenc_bytes(jsonenc* e, upb_StringView str) { + /* This is the regular base64, not the "web-safe" version. */ + static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + const unsigned char* ptr = (unsigned char*)str.data; + const unsigned char* end = UPB_PTRADD(ptr, str.size); + char buf[4]; + + jsonenc_putstr(e, "\""); + + while (end - ptr >= 3) { + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)]; + buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)]; + buf[3] = base64[ptr[2] & 0x3f]; + jsonenc_putbytes(e, buf, 4); + ptr += 3; + } + + switch (end - ptr) { + case 2: + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)]; + buf[2] = base64[(ptr[1] & 0xf) << 2]; + buf[3] = '='; + jsonenc_putbytes(e, buf, 4); + break; + case 1: + buf[0] = base64[ptr[0] >> 2]; + buf[1] = base64[((ptr[0] & 0x3) << 4)]; + buf[2] = '='; + buf[3] = '='; + jsonenc_putbytes(e, buf, 4); + break; + } + + jsonenc_putstr(e, "\""); +} + +static void jsonenc_stringbody(jsonenc* e, upb_StringView str) { + const char* ptr = str.data; + const char* end = UPB_PTRADD(ptr, str.size); + + while (ptr < end) { + switch (*ptr) { + case '\n': + jsonenc_putstr(e, "\\n"); + break; + case '\r': + jsonenc_putstr(e, "\\r"); + break; + case '\t': + jsonenc_putstr(e, "\\t"); + break; + case '\"': + jsonenc_putstr(e, "\\\""); + break; + case '\f': + jsonenc_putstr(e, "\\f"); + break; + case '\b': + jsonenc_putstr(e, "\\b"); + break; + case '\\': + jsonenc_putstr(e, "\\\\"); + break; + default: + if ((uint8_t)*ptr < 0x20) { + jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr); + } else { + /* This could be a non-ASCII byte. We rely on the string being valid + * UTF-8. */ + jsonenc_putbytes(e, ptr, 1); + } + break; + } + ptr++; + } +} + +static void jsonenc_string(jsonenc* e, upb_StringView str) { + jsonenc_putstr(e, "\""); + jsonenc_stringbody(e, str); + jsonenc_putstr(e, "\""); +} + +static bool upb_JsonEncode_HandleSpecialDoubles(jsonenc* e, double val) { + if (val == INFINITY) { + jsonenc_putstr(e, "\"Infinity\""); + } else if (val == -INFINITY) { + jsonenc_putstr(e, "\"-Infinity\""); + } else if (val != val) { + jsonenc_putstr(e, "\"NaN\""); + } else { + return false; + } + return true; +} + +static void upb_JsonEncode_Double(jsonenc* e, double val) { + if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return; + char buf[32]; + _upb_EncodeRoundTripDouble(val, buf, sizeof(buf)); + jsonenc_putstr(e, buf); +} + +static void upb_JsonEncode_Float(jsonenc* e, float val) { + if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return; + char buf[32]; + _upb_EncodeRoundTripFloat(val, buf, sizeof(buf)); + jsonenc_putstr(e, buf); +} + +static void jsonenc_wrapper(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(m, 1); + upb_MessageValue val = upb_Message_GetFieldByDef(msg, val_f); + jsonenc_scalar(e, val, val_f); +} + +static const upb_MessageDef* jsonenc_getanymsg(jsonenc* e, + upb_StringView type_url) { + /* Find last '/', if any. */ + const char* end = type_url.data + type_url.size; + const char* ptr = end; + const upb_MessageDef* ret; + + if (!e->ext_pool) { + jsonenc_err(e, "Tried to encode Any, but no symtab was provided"); + } + + if (type_url.size == 0) goto badurl; + + while (true) { + if (--ptr == type_url.data) { + /* Type URL must contain at least one '/', with host before. */ + goto badurl; + } + if (*ptr == '/') { + ptr++; + break; + } + } + + ret = upb_DefPool_FindMessageByNameWithSize(e->ext_pool, ptr, end - ptr); + + if (!ret) { + jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr); + } + + return ret; + +badurl: + jsonenc_errf(e, "Bad type URL: " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(type_url)); +} + +static void jsonenc_any(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2); + upb_StringView type_url = upb_Message_GetFieldByDef(msg, type_url_f).str_val; + upb_StringView value = upb_Message_GetFieldByDef(msg, value_f).str_val; + const upb_MessageDef* any_m = jsonenc_getanymsg(e, type_url); + const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); + upb_Arena* arena = jsonenc_arena(e); + upb_Message* any = upb_Message_New(any_layout, arena); + + if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) != + kUpb_DecodeStatus_Ok) { + jsonenc_err(e, "Error decoding message in Any"); + } + + jsonenc_putstr(e, "{\"@type\":"); + jsonenc_string(e, type_url); + + if (upb_MessageDef_WellKnownType(any_m) == kUpb_WellKnown_Unspecified) { + /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */ + jsonenc_msgfields(e, any, any_m, false); + } else { + /* Well-known type: {"@type": "...","value": <well-known encoding>} */ + jsonenc_putstr(e, ",\"value\":"); + jsonenc_msgfield(e, any, any_m); + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_putsep(jsonenc* e, const char* str, bool* first) { + if (*first) { + *first = false; + } else { + jsonenc_putstr(e, str); + } +} + +static void jsonenc_fieldpath(jsonenc* e, upb_StringView path) { + const char* ptr = path.data; + const char* end = ptr + path.size; + + while (ptr < end) { + char ch = *ptr; + + if (ch >= 'A' && ch <= 'Z') { + jsonenc_err(e, "Field mask element may not have upper-case letter."); + } else if (ch == '_') { + if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') { + jsonenc_err(e, "Underscore must be followed by a lowercase letter."); + } + ch = *++ptr - 32; + } + + jsonenc_putbytes(e, &ch, 1); + ptr++; + } +} + +static void jsonenc_fieldmask(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_Array* paths = upb_Message_GetFieldByDef(msg, paths_f).array_val; + bool first = true; + size_t i, n = 0; + + if (paths) n = upb_Array_Size(paths); + + jsonenc_putstr(e, "\""); + + for (i = 0; i < n; i++) { + jsonenc_putsep(e, ",", &first); + jsonenc_fieldpath(e, upb_Array_Get(paths, i).str_val); + } + + jsonenc_putstr(e, "\""); +} + +static void jsonenc_struct(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + jsonenc_putstr(e, "{"); + + const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_Map* fields = upb_Message_GetFieldByDef(msg, fields_f).map_val; + + if (fields) { + const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f); + const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2); + + size_t iter = kUpb_Map_Begin; + bool first = true; + + upb_MessageValue key, val; + while (upb_Map_Next(fields, &key, &val, &iter)) { + jsonenc_putsep(e, ",", &first); + jsonenc_string(e, key.str_val); + jsonenc_putstr(e, ":"); + jsonenc_value(e, val.msg_val, upb_FieldDef_MessageSubDef(value_f)); + } + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_listvalue(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1); + const upb_MessageDef* values_m = upb_FieldDef_MessageSubDef(values_f); + const upb_Array* values = upb_Message_GetFieldByDef(msg, values_f).array_val; + size_t i; + bool first = true; + + jsonenc_putstr(e, "["); + + if (values) { + const size_t size = upb_Array_Size(values); + for (i = 0; i < size; i++) { + upb_MessageValue elem = upb_Array_Get(values, i); + + jsonenc_putsep(e, ",", &first); + jsonenc_value(e, elem.msg_val, values_m); + } + } + + jsonenc_putstr(e, "]"); +} + +static void jsonenc_value(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + /* TODO: do we want a reflection method to get oneof case? */ + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; + + if (!upb_Message_Next(msg, m, NULL, &f, &val, &iter)) { + jsonenc_err(e, "No value set in Value proto"); + } + + switch (upb_FieldDef_Number(f)) { + case 1: + jsonenc_putstr(e, "null"); + break; + case 2: + if (upb_JsonEncode_HandleSpecialDoubles(e, val.double_val)) { + jsonenc_err( + e, + "google.protobuf.Value cannot encode double values for " + "infinity or nan, because they would be parsed as a string"); + } + upb_JsonEncode_Double(e, val.double_val); + break; + case 3: + jsonenc_string(e, val.str_val); + break; + case 4: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case 5: + jsonenc_struct(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + break; + case 6: + jsonenc_listvalue(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + break; + } +} + +static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + switch (upb_MessageDef_WellKnownType(m)) { + case kUpb_WellKnown_Unspecified: + jsonenc_msg(e, msg, m); + break; + case kUpb_WellKnown_Any: + jsonenc_any(e, msg, m); + break; + case kUpb_WellKnown_FieldMask: + jsonenc_fieldmask(e, msg, m); + break; + case kUpb_WellKnown_Duration: + jsonenc_duration(e, msg, m); + break; + case kUpb_WellKnown_Timestamp: + jsonenc_timestamp(e, msg, m); + break; + case kUpb_WellKnown_DoubleValue: + case kUpb_WellKnown_FloatValue: + case kUpb_WellKnown_Int64Value: + case kUpb_WellKnown_UInt64Value: + case kUpb_WellKnown_Int32Value: + case kUpb_WellKnown_UInt32Value: + case kUpb_WellKnown_StringValue: + case kUpb_WellKnown_BytesValue: + case kUpb_WellKnown_BoolValue: + jsonenc_wrapper(e, msg, m); + break; + case kUpb_WellKnown_Value: + jsonenc_value(e, msg, m); + break; + case kUpb_WellKnown_ListValue: + jsonenc_listvalue(e, msg, m); + break; + case kUpb_WellKnown_Struct: + jsonenc_struct(e, msg, m); + break; + } +} + +static void jsonenc_scalar(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case kUpb_CType_Float: + upb_JsonEncode_Float(e, val.float_val); + break; + case kUpb_CType_Double: + upb_JsonEncode_Double(e, val.double_val); + break; + case kUpb_CType_Int32: + jsonenc_printf(e, "%" PRId32, val.int32_val); + break; + case kUpb_CType_UInt32: + jsonenc_printf(e, "%" PRIu32, val.uint32_val); + break; + case kUpb_CType_Int64: + jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val); + break; + case kUpb_CType_UInt64: + jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val); + break; + case kUpb_CType_String: + jsonenc_string(e, val.str_val); + break; + case kUpb_CType_Bytes: + jsonenc_bytes(e, val.str_val); + break; + case kUpb_CType_Enum: + jsonenc_enum(val.int32_val, f, e); + break; + case kUpb_CType_Message: + jsonenc_msgfield(e, val.msg_val, upb_FieldDef_MessageSubDef(f)); + break; + } +} + +static void jsonenc_mapkey(jsonenc* e, upb_MessageValue val, + const upb_FieldDef* f) { + jsonenc_putstr(e, "\""); + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + jsonenc_putstr(e, val.bool_val ? "true" : "false"); + break; + case kUpb_CType_Int32: + jsonenc_printf(e, "%" PRId32, val.int32_val); + break; + case kUpb_CType_UInt32: + jsonenc_printf(e, "%" PRIu32, val.uint32_val); + break; + case kUpb_CType_Int64: + jsonenc_printf(e, "%" PRId64, val.int64_val); + break; + case kUpb_CType_UInt64: + jsonenc_printf(e, "%" PRIu64, val.uint64_val); + break; + case kUpb_CType_String: + jsonenc_stringbody(e, val.str_val); + break; + default: + UPB_UNREACHABLE(); + } + + jsonenc_putstr(e, "\":"); +} + +static void jsonenc_array(jsonenc* e, const upb_Array* arr, + const upb_FieldDef* f) { + size_t i; + size_t size = arr ? upb_Array_Size(arr) : 0; + bool first = true; + + jsonenc_putstr(e, "["); + + for (i = 0; i < size; i++) { + jsonenc_putsep(e, ",", &first); + jsonenc_scalar(e, upb_Array_Get(arr, i), f); + } + + jsonenc_putstr(e, "]"); +} + +static void jsonenc_map(jsonenc* e, const upb_Map* map, const upb_FieldDef* f) { + jsonenc_putstr(e, "{"); + + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1); + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2); + + if (map) { + size_t iter = kUpb_Map_Begin; + bool first = true; + + upb_MessageValue key, val; + while (upb_Map_Next(map, &key, &val, &iter)) { + jsonenc_putsep(e, ",", &first); + jsonenc_mapkey(e, key, key_f); + jsonenc_scalar(e, val, val_f); + } + } + + jsonenc_putstr(e, "}"); +} + +static void jsonenc_fieldval(jsonenc* e, const upb_FieldDef* f, + upb_MessageValue val, bool* first) { + const char* name; + + jsonenc_putsep(e, ",", first); + + if (upb_FieldDef_IsExtension(f)) { + // TODO: For MessageSet, I would have expected this to print the message + // name here, but Python doesn't appear to do this. We should do more + // research here about what various implementations do. + jsonenc_printf(e, "\"[%s]\":", upb_FieldDef_FullName(f)); + } else { + if (e->options & upb_JsonEncode_UseProtoNames) { + name = upb_FieldDef_Name(f); + } else { + name = upb_FieldDef_JsonName(f); + } + jsonenc_printf(e, "\"%s\":", name); + } + + if (upb_FieldDef_IsMap(f)) { + jsonenc_map(e, val.map_val, f); + } else if (upb_FieldDef_IsRepeated(f)) { + jsonenc_array(e, val.array_val, f); + } else { + jsonenc_scalar(e, val, f); + } +} + +static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m, bool first) { + upb_MessageValue val; + const upb_FieldDef* f; + + if (e->options & upb_JsonEncode_EmitDefaults) { + /* Iterate over all fields. */ + int i = 0; + int n = upb_MessageDef_FieldCount(m); + for (i = 0; i < n; i++) { + f = upb_MessageDef_Field(m, i); + if (!upb_FieldDef_HasPresence(f) || upb_Message_HasFieldByDef(msg, f)) { + jsonenc_fieldval(e, f, upb_Message_GetFieldByDef(msg, f), &first); + } + } + } else { + /* Iterate over non-empty fields. */ + size_t iter = kUpb_Message_Begin; + while (upb_Message_Next(msg, m, e->ext_pool, &f, &val, &iter)) { + jsonenc_fieldval(e, f, val, &first); + } + } +} + +static void jsonenc_msg(jsonenc* e, const upb_Message* msg, + const upb_MessageDef* m) { + jsonenc_putstr(e, "{"); + jsonenc_msgfields(e, msg, m, true); + jsonenc_putstr(e, "}"); +} + +static size_t jsonenc_nullz(jsonenc* e, size_t size) { + size_t ret = e->ptr - e->buf + e->overflow; + + if (size > 0) { + if (e->ptr == e->end) e->ptr--; + *e->ptr = '\0'; + } + + return ret; +} + +static size_t upb_JsonEncoder_Encode(jsonenc* const e, + const upb_Message* const msg, + const upb_MessageDef* const m, + const size_t size) { + if (UPB_SETJMP(e->err) != 0) return -1; + + jsonenc_msgfield(e, msg, m); + if (e->arena) upb_Arena_Free(e->arena); + return jsonenc_nullz(e, size); +} + +size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, char* buf, + size_t size, upb_Status* status) { + jsonenc e; + + e.buf = buf; + e.ptr = buf; + e.end = UPB_PTRADD(buf, size); + e.overflow = 0; + e.options = options; + e.ext_pool = ext_pool; + e.status = status; + e.arena = NULL; + + return upb_JsonEncoder_Encode(&e, msg, m, size); +} + + +// Must be last. + +const char* upb_BufToUint64(const char* ptr, const char* end, uint64_t* val) { + uint64_t u64 = 0; + while (ptr < end) { + unsigned ch = *ptr - '0'; + if (ch >= 10) break; + if (u64 > UINT64_MAX / 10 || u64 * 10 > UINT64_MAX - ch) { + return NULL; // integer overflow + } + u64 *= 10; + u64 += ch; + ptr++; + } + + *val = u64; + return ptr; +} + +const char* upb_BufToInt64(const char* ptr, const char* end, int64_t* val, + bool* is_neg) { + bool neg = false; + uint64_t u64; + + if (ptr != end && *ptr == '-') { + ptr++; + neg = true; + } + + ptr = upb_BufToUint64(ptr, end, &u64); + if (!ptr || u64 > (uint64_t)INT64_MAX + neg) { + return NULL; // integer overflow + } + + *val = neg ? -u64 : u64; + if (is_neg) *is_neg = neg; + return ptr; +} + + +#include <float.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +// Must be last. + +/* Miscellaneous utilities ****************************************************/ + +static void upb_FixLocale(char* p) { + /* printf() is dependent on locales; sadly there is no easy and portable way + * to avoid this. This little post-processing step will translate 1,2 -> 1.2 + * since JSON needs the latter. Arguably a hack, but it is simple and the + * alternatives are far more complicated, platform-dependent, and/or larger + * in code size. */ + for (; *p; p++) { + if (*p == ',') *p = '.'; + } +} + +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + if (isnan(val)) { + snprintf(buf, size, "%s", "nan"); + return; + } + snprintf(buf, size, "%.*g", DBL_DIG, val); + if (strtod(buf, NULL) != val) { + snprintf(buf, size, "%.*g", DBL_DIG + 2, val); + assert(strtod(buf, NULL) == val); + } + upb_FixLocale(buf); +} + +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size) { + assert(size >= kUpb_RoundTripBufferSize); + if (isnan(val)) { + snprintf(buf, size, "%s", "nan"); + return; + } + snprintf(buf, size, "%.*g", FLT_DIG, val); + if (strtof(buf, NULL) != val) { + snprintf(buf, size, "%.*g", FLT_DIG + 3, val); + assert(strtof(buf, NULL) == val); + } + upb_FixLocale(buf); +} + + +#include <stdlib.h> +#include <string.h> + +// Must be last. + +// Determine the locale-specific radix character by calling sprintf() to print +// the number 1.5, then stripping off the digits. As far as I can tell, this +// is the only portable, thread-safe way to get the C library to divulge the +// locale's radix character. No, localeconv() is NOT thread-safe. + +static int GetLocaleRadix(char *data, size_t capacity) { + char temp[16]; + const int size = snprintf(temp, sizeof(temp), "%.1f", 1.5); + UPB_ASSERT(temp[0] == '1'); + UPB_ASSERT(temp[size - 1] == '5'); + if (size < capacity) { + return 0; + } + temp[size - 1] = '\0'; + strncpy(data, temp + 1, size); + return size - 2; +} + +// Populates a string identical to *input except that the character pointed to +// by pos (which should be '.') is replaced with the locale-specific radix. + +static void LocalizeRadix(const char *input, const char *pos, char *output, + int output_size) { + const int len1 = pos - input; + + char radix[8]; + const int len2 = GetLocaleRadix(radix, sizeof(radix)); + + const int n = output_size - len1 - len2 - 1; + if (n < 0) { + return; + } + + memcpy(output, input, len1); + memcpy(output + len1, radix, len2); + strncpy(output + len1 + len2, input + len1 + 1, n); + output[output_size - 1] = '\0'; +} + +double _upb_NoLocaleStrtod(const char *str, char **endptr) { + // We cannot simply set the locale to "C" temporarily with setlocale() + // as this is not thread-safe. Instead, we try to parse in the current + // locale first. If parsing stops at a '.' character, then this is a + // pretty good hint that we're actually in some other locale in which + // '.' is not the radix character. + + char *temp_endptr; + double result = strtod(str, &temp_endptr); + if (endptr != NULL) *endptr = temp_endptr; + if (*temp_endptr != '.') return result; + + // Parsing halted on a '.'. Perhaps we're in a different locale? Let's + // try to replace the '.' with a locale-specific radix character and + // try again. + + char localized[80]; + LocalizeRadix(str, temp_endptr, localized, sizeof localized); + char *localized_endptr; + result = strtod(localized, &localized_endptr); + if ((localized_endptr - &localized[0]) > (temp_endptr - str)) { + // This attempt got further, so replacing the decimal must have helped. + // Update endptr to point at the right location. + if (endptr != NULL) { + // size_diff is non-zero if the localized radix has multiple bytes. + int size_diff = strlen(localized) - strlen(str); + *endptr = (char *)str + (localized_endptr - &localized[0] - size_diff); + } + } + + return result; +} + + +// Must be last. + +int upb_Unicode_ToUTF8(uint32_t cp, char* out) { + if (cp <= 0x7f) { + out[0] = cp; + return 1; + } + if (cp <= 0x07ff) { + out[0] = (cp >> 6) | 0xc0; + out[1] = (cp & 0x3f) | 0x80; + return 2; + } + if (cp <= 0xffff) { + out[0] = (cp >> 12) | 0xe0; + out[1] = ((cp >> 6) & 0x3f) | 0x80; + out[2] = (cp & 0x3f) | 0x80; + return 3; + } + if (cp <= 0x10ffff) { + out[0] = (cp >> 18) | 0xf0; + out[1] = ((cp >> 12) & 0x3f) | 0x80; + out[2] = ((cp >> 6) & 0x3f) | 0x80; + out[3] = (cp & 0x3f) | 0x80; + return 4; + } + return 0; +} + + +#include <stdlib.h> + +// Must be last. + +static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, + size_t size, size_t* actual_size) { + UPB_UNUSED(alloc); + UPB_UNUSED(oldsize); + UPB_UNUSED(actual_size); + if (size == 0) { + free(ptr); + return NULL; + } else { + return realloc(ptr, size); + } +} + +upb_alloc upb_alloc_global = {&upb_global_allocfunc}; + + +#include <string.h> + + +#ifdef UPB_TRACING_ENABLED +#include <stdatomic.h> +#endif + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +static UPB_ATOMIC(size_t) g_max_block_size = UPB_DEFAULT_MAX_BLOCK_SIZE; + +void upb_Arena_SetMaxBlockSize(size_t max) { + UPB_ASSERT(max <= UINT32_MAX); + upb_Atomic_Store(&g_max_block_size, max, memory_order_relaxed); +} + +typedef struct upb_MemBlock { + struct upb_MemBlock* next; + // Size of the actual allocation. + // Size of 0 means this is a upb_ArenaRef. + size_t size; + // Data follows. +} upb_MemBlock; + +// A special block type that indicates a reference to another arena. +// When this arena is freed, a ref is released on the referenced arena. +// size must be 0. +typedef struct upb_ArenaRef { + upb_MemBlock prefix; // size is always zero + const upb_Arena* arena; +#ifndef NDEBUG + const struct upb_ArenaRef* next_ref; +#endif +} upb_ArenaRef; + +typedef struct upb_ArenaInternal { + // upb_alloc* together with a low bit which signals if there is an initial + // block. + uintptr_t block_alloc; + + // Linked list of blocks to free/cleanup. + upb_MemBlock* blocks; + +#ifndef NDEBUG + // Stack of pointers to other arenas that this arena owns. + // Used for debug-only ref cycle checks. + UPB_ATOMIC(const upb_ArenaRef*) refs; +#endif + + // Size of the last block we allocated in the normal exponential scheme. + uint32_t last_block_size; + + // A hint that grows whenever we perform a "one-off" allocation into a a + // dedicated block. This helps us determine if these outlier blocks are + // actually common enough that we should switch back to the normal exponential + // scheme at the larger size. + uint32_t size_hint; + + // All non atomic members used during allocation must be above this point, and + // are used by _SwapIn/_SwapOut + + // Total space allocated in blocks, atomic only for SpaceAllocated + UPB_ATOMIC(uintptr_t) space_allocated; + + // The cleanup for the allocator. This is called after all the blocks are + // freed in an arena. + upb_AllocCleanupFunc* upb_alloc_cleanup; + + // When multiple arenas are fused together, each arena points to a parent + // arena (root points to itself). The root tracks how many live arenas + // reference it. + + // The low bit is tagged: + // 0: pointer to parent + // 1: count, left shifted by one + UPB_ATOMIC(uintptr_t) parent_or_count; + + // All nodes that are fused together are in a singly-linked list. + // == NULL at end of list. + UPB_ATOMIC(struct upb_ArenaInternal*) next; + + // - If the low bit is set, is a pointer to the tail of the list (populated + // for roots, set to self for roots with no fused arenas). This is best + // effort, and it may not always reflect the true tail, but it will always + // be a valid node in the list. This is useful for finding the list tail + // without having to walk the entire list. + // - If the low bit is not set, is a pointer to the previous node in the list, + // such that a->previous_or_tail->next == a. + UPB_ATOMIC(uintptr_t) previous_or_tail; + + // We use a different UPB_XSAN_MEMBER than the one in upb_Arena because the + // two are distinct synchronization domains. The upb_Arena.ptr member is + // not published in the allocation path, so it is not synchronized with + // respect to operations performed in this file such as Fuse, Free, + // SpaceAllocated, etc. This means that it is not safe to read or write + // the upb_Arena.ptr member in those functions. + UPB_XSAN_MEMBER +} upb_ArenaInternal; + +// All public + private state for an arena. +typedef struct { + upb_Arena head; + upb_ArenaInternal body; +} upb_ArenaState; + +typedef struct { + upb_ArenaInternal* root; + uintptr_t tagged_count; +} upb_ArenaRoot; + +static const size_t kUpb_MemblockReserve = + UPB_ALIGN_MALLOC(sizeof(upb_MemBlock)); + +static const size_t kUpb_ArenaRefReserve = + UPB_ALIGN_MALLOC(sizeof(upb_ArenaRef)); + +// Extracts the (upb_ArenaInternal*) from a (upb_Arena*) +static upb_ArenaInternal* upb_Arena_Internal(const upb_Arena* a) { + return &((upb_ArenaState*)a)->body; +} + +static bool _upb_Arena_IsTaggedRefcount(uintptr_t parent_or_count) { + return (parent_or_count & 1) == 1; +} + +static bool _upb_Arena_IsTaggedPointer(uintptr_t parent_or_count) { + return (parent_or_count & 1) == 0; +} + +static uintptr_t _upb_Arena_RefCountFromTagged(uintptr_t parent_or_count) { + UPB_ASSERT(_upb_Arena_IsTaggedRefcount(parent_or_count)); + return parent_or_count >> 1; +} + +static uintptr_t _upb_Arena_TaggedFromRefcount(uintptr_t refcount) { + uintptr_t parent_or_count = (refcount << 1) | 1; + UPB_ASSERT(_upb_Arena_IsTaggedRefcount(parent_or_count)); + return parent_or_count; +} + +static upb_ArenaInternal* _upb_Arena_PointerFromTagged( + uintptr_t parent_or_count) { + UPB_ASSERT(_upb_Arena_IsTaggedPointer(parent_or_count)); + return (upb_ArenaInternal*)parent_or_count; +} + +static uintptr_t _upb_Arena_TaggedFromPointer(upb_ArenaInternal* ai) { + uintptr_t parent_or_count = (uintptr_t)ai; + UPB_ASSERT(_upb_Arena_IsTaggedPointer(parent_or_count)); + return parent_or_count; +} + +static bool _upb_Arena_IsTaggedTail(uintptr_t previous_or_tail) { + return (previous_or_tail & 1) == 1; +} + +static bool _upb_Arena_IsTaggedPrevious(uintptr_t previous_or_tail) { + return (previous_or_tail & 1) == 0; +} + +static upb_ArenaInternal* _upb_Arena_TailFromTagged( + uintptr_t previous_or_tail) { + UPB_ASSERT(_upb_Arena_IsTaggedTail(previous_or_tail)); + return (upb_ArenaInternal*)(previous_or_tail ^ 1); +} + +static uintptr_t _upb_Arena_TaggedFromTail(upb_ArenaInternal* tail) { + uintptr_t previous_or_tail = (uintptr_t)tail | 1; + UPB_ASSERT(_upb_Arena_IsTaggedTail(previous_or_tail)); + return previous_or_tail; +} + +static upb_ArenaInternal* _upb_Arena_PreviousFromTagged( + uintptr_t previous_or_tail) { + UPB_ASSERT(_upb_Arena_IsTaggedPrevious(previous_or_tail)); + return (upb_ArenaInternal*)previous_or_tail; +} + +static uintptr_t _upb_Arena_TaggedFromPrevious(upb_ArenaInternal* ai) { + uintptr_t previous = (uintptr_t)ai; + UPB_ASSERT(_upb_Arena_IsTaggedPrevious(previous)); + return previous; +} + +static upb_alloc* _upb_ArenaInternal_BlockAlloc(upb_ArenaInternal* ai) { + return (upb_alloc*)(ai->block_alloc & ~0x1); +} + +static uintptr_t _upb_Arena_MakeBlockAlloc(upb_alloc* alloc, bool has_initial) { + uintptr_t alloc_uint = (uintptr_t)alloc; + UPB_ASSERT((alloc_uint & 1) == 0); + return alloc_uint | (has_initial ? 1 : 0); +} + +static bool _upb_ArenaInternal_HasInitialBlock(upb_ArenaInternal* ai) { + return ai->block_alloc & 0x1; +} + +#ifdef UPB_TRACING_ENABLED +static void (*_init_arena_trace_handler)(const upb_Arena*, size_t size) = NULL; +static void (*_fuse_arena_trace_handler)(const upb_Arena*, + const upb_Arena*) = NULL; +static void (*_free_arena_trace_handler)(const upb_Arena*) = NULL; + +void upb_Arena_SetTraceHandler( + void (*initArenaTraceHandler)(const upb_Arena*, size_t size), + void (*fuseArenaTraceHandler)(const upb_Arena*, const upb_Arena*), + void (*freeArenaTraceHandler)(const upb_Arena*)) { + _init_arena_trace_handler = initArenaTraceHandler; + _fuse_arena_trace_handler = fuseArenaTraceHandler; + _free_arena_trace_handler = freeArenaTraceHandler; +} + +void upb_Arena_LogInit(const upb_Arena* arena, size_t size) { + if (_init_arena_trace_handler) { + _init_arena_trace_handler(arena, size); + } +} +void upb_Arena_LogFuse(const upb_Arena* arena1, const upb_Arena* arena2) { + if (_fuse_arena_trace_handler) { + _fuse_arena_trace_handler(arena1, arena2); + } +} +void upb_Arena_LogFree(const upb_Arena* arena) { + if (_free_arena_trace_handler) { + _free_arena_trace_handler(arena); + } +} +#endif // UPB_TRACING_ENABLED + +// If the param a is already the root, provides no memory order of refcount. +// If it has a parent, then acquire memory order is provided for both the root +// and the refcount. Thread safe. +static upb_ArenaRoot _upb_Arena_FindRoot(upb_ArenaInternal* ai) { + uintptr_t poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_relaxed); + if (_upb_Arena_IsTaggedRefcount(poc)) { + // Fast, relaxed path - arenas that have never been fused to a parent only + // need relaxed memory order, since they're returning themselves and the + // refcount. + return (upb_ArenaRoot){.root = ai, .tagged_count = poc}; + } + // Slow path needs acquire order; reloading is cheaper than a fence on ARM + // (LDA vs DMB ISH). Even though this is a reread, we know it must be a tagged + // pointer because if this Arena isn't a root, it can't ever become one. + poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_acquire); + do { + upb_ArenaInternal* next = _upb_Arena_PointerFromTagged(poc); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(next)); + UPB_ASSERT(ai != next); + poc = upb_Atomic_Load(&next->parent_or_count, memory_order_acquire); + + if (_upb_Arena_IsTaggedPointer(poc)) { + // To keep complexity down, we lazily collapse levels of the tree. This + // keeps it flat in the final case, but doesn't cost much incrementally. + // + // Path splitting keeps time complexity down, see: + // https://en.wikipedia.org/wiki/Disjoint-set_data_structure + UPB_ASSERT(ai != _upb_Arena_PointerFromTagged(poc)); + upb_Atomic_Store(&ai->parent_or_count, poc, memory_order_release); + } + ai = next; + } while (_upb_Arena_IsTaggedPointer(poc)); + return (upb_ArenaRoot){.root = ai, .tagged_count = poc}; +} + +uintptr_t upb_Arena_SpaceAllocated(const upb_Arena* arena, + size_t* fused_count) { + upb_ArenaInternal* ai = upb_Arena_Internal(arena); + uintptr_t memsize = 0; + size_t local_fused_count = 0; + // Our root would get updated by any racing fuses before our target arena + // became reachable from the root via the linked list; in order to preserve + // monotonic output (any arena counted by a previous invocation is counted by + // this one), we instead iterate forwards and backwards so that we only see + // the results of completed fuses. + uintptr_t previous_or_tail = + upb_Atomic_Load(&ai->previous_or_tail, memory_order_acquire); + while (_upb_Arena_IsTaggedPrevious(previous_or_tail)) { + upb_ArenaInternal* previous = + _upb_Arena_PreviousFromTagged(previous_or_tail); + UPB_ASSERT(previous != ai); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(previous)); + // Unfortunate macro behavior; prior to C11 when using nonstandard atomics + // this returns a void* and can't be used with += without an intermediate + // conversion to an integer. + // Relaxed is safe - no subsequent reads depend this one + uintptr_t allocated = + upb_Atomic_Load(&previous->space_allocated, memory_order_relaxed); + memsize += allocated; + previous_or_tail = + upb_Atomic_Load(&previous->previous_or_tail, memory_order_acquire); + local_fused_count++; + } + while (ai != NULL) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(ai)); + // Unfortunate macro behavior; prior to C11 when using nonstandard atomics + // this returns a void* and can't be used with += without an intermediate + // conversion to an integer. + // Relaxed is safe - no subsequent reads depend this one + uintptr_t allocated = + upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed); + memsize += allocated; + ai = upb_Atomic_Load(&ai->next, memory_order_acquire); + local_fused_count++; + } + + if (fused_count) *fused_count = local_fused_count; + return memsize; +} + +uint32_t upb_Arena_DebugRefCount(const upb_Arena* a) { + uintptr_t tagged = _upb_Arena_FindRoot(upb_Arena_Internal(a)).tagged_count; + return (uint32_t)_upb_Arena_RefCountFromTagged(tagged); +} + +#if UPB_ENABLE_REF_CYCLE_CHECKS + +bool upb_Arena_HasRefChain(const upb_Arena* from, const upb_Arena* to) { + upb_ArenaInternal* ai = upb_Arena_Internal(from); + upb_ArenaInternal* current; + + if (upb_Arena_IsFused(from, to)) return true; + + // 1. Traverse backward to the start of a consistent segment. + uintptr_t previous_or_tail = + upb_Atomic_Load(&ai->previous_or_tail, memory_order_acquire); + while (_upb_Arena_IsTaggedPrevious(previous_or_tail)) { + ai = _upb_Arena_PreviousFromTagged(previous_or_tail); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(ai)); + previous_or_tail = + upb_Atomic_Load(&ai->previous_or_tail, memory_order_acquire); + } + + // 2. Traverse forward through all arenas in the fuse group. + current = ai; + while (current != NULL) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(current)); + const upb_ArenaRef* ref = + upb_Atomic_Load(¤t->refs, memory_order_acquire); + while (ref != NULL) { + if (ref->arena == to || upb_Arena_HasRefChain(ref->arena, to)) { + return true; + } + ref = ref->next_ref; + } + current = upb_Atomic_Load(¤t->next, memory_order_acquire); + } + return false; +} + +#endif + +static upb_MemBlock* _upb_Arena_AllocBlockInternal(upb_alloc* alloc, + size_t size) { + UPB_ASSERT(size >= kUpb_MemblockReserve); + upb_SizedPtr alloc_result = upb_SizeReturningMalloc(alloc, size); + if (!alloc_result.p) return NULL; + upb_MemBlock* block = alloc_result.p; + block->size = alloc_result.n; + return block; +} + +static upb_MemBlock* _upb_Arena_AllocBlock(upb_Arena* a, size_t size) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + return _upb_Arena_AllocBlockInternal(_upb_ArenaInternal_BlockAlloc(ai), size); +} + +static void _upb_Arena_AddBlock(upb_Arena* a, upb_MemBlock* block) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + + // Atomic add not required here, as threads won't race allocating blocks, plus + // atomic fetch-add is slower than load/add/store on arm devices compiled + // targeting pre-v8.1. Relaxed order is safe as nothing depends on order of + // size allocated. + uintptr_t old_space_allocated = + upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed); + upb_Atomic_Store(&ai->space_allocated, old_space_allocated + block->size, + memory_order_relaxed); + + block->next = ai->blocks; + ai->blocks = block; +} + +static void _upb_Arena_UseBlockInternal(upb_Arena* a, upb_MemBlock* block, + size_t offset) { + size_t block_size = block->size; + char* start = UPB_PTR_AT(block, kUpb_MemblockReserve + offset, char); + a->UPB_PRIVATE(ptr) = start; + a->UPB_PRIVATE(end) = UPB_PTR_AT(block, block_size, char); + UPB_PRIVATE(upb_Xsan_PoisonRegion)(start, a->UPB_PRIVATE(end) - start); + UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(a)); + UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= + block_size - kUpb_MemblockReserve - offset); +} + +static void _upb_Arena_UseBlock(upb_Arena* a, upb_MemBlock* block) { + _upb_Arena_UseBlockInternal(a, block, 0); +} + +static bool _upb_Arena_WouldReduceFreeSpace(upb_Arena* a, size_t size, + size_t block_size) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + size_t current_free = + ai->blocks ? a->UPB_PRIVATE(end) - a->UPB_PRIVATE(ptr) : 0; + size_t future_free = block_size - kUpb_MemblockReserve - size; + return current_free >= future_free; +} + +// Fulfills the allocation request by allocating a new block. Returns NULL on +// allocation failure. +void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t size) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + if (!ai->block_alloc) return NULL; + + // Whether to satisfy the allocation from a one-off block which is right-sized + // for the current allocation. We do this if we suspect that the current + // allocation is an outlier that does not represent the typical size of + // allocations from this arena, or if we would reduce free space by + // using exponential growth. + bool one_off = false; + + // Relaxed order is safe here as we don't need any ordering with the setter. + size_t max_block_size = + upb_Atomic_Load(&g_max_block_size, memory_order_relaxed); + size_t block_size = UPB_MIN(ai->last_block_size * 2, max_block_size); + + if (size + kUpb_MemblockReserve > block_size) { + // A regular doubling would not yield a large enough block. Does size_hint + // indicate that we have consistently needed large blocks? + block_size = UPB_MIN(ai->size_hint * 2, max_block_size); + if (size + kUpb_MemblockReserve > block_size) { + // Even size_hint is not large enough, we will have to do a one-off. + one_off = true; + } + } + + // If switching to a block of this size would *reduce* available free space, + // we might as well make a one-off block instead. + one_off = one_off || _upb_Arena_WouldReduceFreeSpace(a, size, block_size); + + if (one_off) { + // Note: this may exceed the max block size, but that's okay. + block_size = size + kUpb_MemblockReserve; + } + + upb_MemBlock* block = _upb_Arena_AllocBlock(a, block_size); + if (!block) return NULL; + + _upb_Arena_AddBlock(a, block); + + // Recheck size, in case the allocator gave us a much larger block than we + // requested and we want to make it the new allocating region. + if (UPB_UNLIKELY(one_off) && + _upb_Arena_WouldReduceFreeSpace(a, size, block->size)) { + // Increase size_hint, so that a series of one-off allocations will + // eventually convince us to switch to exponential growth at the larger + // size. + ai->size_hint = UPB_MIN(ai->size_hint + (size >> 1), max_block_size >> 1); + char* allocated = UPB_PTR_AT(block, kUpb_MemblockReserve, char); + char* poison_start = allocated + size - UPB_PRIVATE(kUpb_Asan_GuardSize); + UPB_PRIVATE(upb_Xsan_PoisonRegion)( + poison_start, UPB_PTR_AT(block, block->size, char) - poison_start); + return allocated; + } else { + ai->last_block_size = UPB_MIN(block->size, UINT32_MAX); + ai->size_hint = ai->last_block_size; + _upb_Arena_UseBlock(a, block); + UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= size); + return upb_Arena_Malloc(a, size - UPB_PRIVATE(kUpb_Asan_GuardSize)); + } +} + +static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) { + const size_t first_block_overhead = + UPB_ALIGN_MALLOC(kUpb_MemblockReserve + sizeof(upb_ArenaState)); + upb_ArenaState* a; + + if (!alloc) return NULL; + + // We need to malloc the initial block. + size_t block_size = + first_block_overhead + UPB_MAX(256, UPB_ALIGN_MALLOC(first_size) + + UPB_PRIVATE(kUpb_Asan_GuardSize)); + upb_MemBlock* block = _upb_Arena_AllocBlockInternal(alloc, block_size); + if (!block) return NULL; + + // Initialize the arena state in the first block. We "borrow" the memory from + // the block, because we can't yet call upb_Arena_Malloc. + a = UPB_PTR_AT(block, kUpb_MemblockReserve, upb_ArenaState); + a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 0); + a->body.last_block_size = UPB_MIN(block->size, UINT32_MAX); + a->body.size_hint = UPB_MIN(block->size, UINT32_MAX); + upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1)); + upb_Atomic_Init(&a->body.next, NULL); + upb_Atomic_Init(&a->body.previous_or_tail, + _upb_Arena_TaggedFromTail(&a->body)); + upb_Atomic_Init(&a->body.space_allocated, 0); + a->body.blocks = NULL; +#ifndef NDEBUG + a->body.refs = NULL; +#endif + a->body.upb_alloc_cleanup = NULL; + UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body)); + + _upb_Arena_AddBlock(&a->head, block); + _upb_Arena_UseBlockInternal(&a->head, block, + UPB_ALIGN_MALLOC(sizeof(upb_ArenaState))); + + return &a->head; +} + +upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) { + UPB_STATIC_ASSERT(UPB_ARENA_SIZE_HACK >= sizeof(upb_ArenaState), + "Need to update UPB_ARENA_SIZE_HACK"); + upb_ArenaState* a; + + if (mem) { + /* Align initial pointer up so that we return properly-aligned pointers. */ + void* aligned = (void*)UPB_ALIGN_MALLOC((uintptr_t)mem); + size_t delta = (uintptr_t)aligned - (uintptr_t)mem; + n = delta <= n ? n - delta : 0; + mem = aligned; + } + if (UPB_UNLIKELY(n < sizeof(upb_ArenaState) || !mem)) { + upb_Arena* ret = _upb_Arena_InitSlow(alloc, mem ? 0 : n); +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogInit(ret, n); +#endif + return ret; + } + + a = mem; + + upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1)); + upb_Atomic_Init(&a->body.next, NULL); + upb_Atomic_Init(&a->body.previous_or_tail, + _upb_Arena_TaggedFromTail(&a->body)); + upb_Atomic_Init(&a->body.space_allocated, 0); + a->body.blocks = NULL; +#ifndef NDEBUG + a->body.refs = NULL; +#endif + a->body.size_hint = 128; + a->body.last_block_size = 128; + a->body.upb_alloc_cleanup = NULL; + a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 1); + a->head.UPB_PRIVATE(ptr) = (void*)UPB_ALIGN_MALLOC((uintptr_t)(a + 1)); + a->head.UPB_PRIVATE(end) = UPB_PTR_AT(mem, n, char); + UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body)); +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogInit(&a->head, n); +#endif + return &a->head; +} + +static void _upb_Arena_DoFree(upb_ArenaInternal* ai) { + UPB_ASSERT(_upb_Arena_RefCountFromTagged(ai->parent_or_count) == 1); + while (ai != NULL) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(ai)); + // Load first since arena itself is likely from one of its blocks. Relaxed + // order is safe because fused arena ordering is provided by the reference + // count, and fuse is not permitted to race with the final decrement. + upb_ArenaInternal* next_arena = + (upb_ArenaInternal*)upb_Atomic_Load(&ai->next, memory_order_relaxed); + // Freeing may have memory barriers that confuse tsan, so assert immediately + // after load here + if (next_arena) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(next_arena)); + } + upb_alloc* block_alloc = _upb_ArenaInternal_BlockAlloc(ai); + upb_MemBlock* block = ai->blocks; + upb_AllocCleanupFunc* alloc_cleanup = *ai->upb_alloc_cleanup; + while (block != NULL) { + // Load first since we are deleting block. + upb_MemBlock* next_block = block->next; + if (block->size == 0) { + // If the block is an arena ref, then we need to release our ref on the + // referenced arena. + upb_ArenaRef* ref = (upb_ArenaRef*)block; + upb_Arena_DecRefFor((upb_Arena*)ref->arena, ai); + } else { + upb_free_sized(block_alloc, block, block->size); + } + block = next_block; + } + if (alloc_cleanup != NULL) { + alloc_cleanup(block_alloc); + } + ai = next_arena; + } +} + +void upb_Arena_Free(upb_Arena* a) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + // Cannot be replaced with _upb_Arena_FindRoot, as that provides only a + // relaxed read of the refcount if ai is already the root. + uintptr_t poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_acquire); +retry: + while (_upb_Arena_IsTaggedPointer(poc)) { + ai = _upb_Arena_PointerFromTagged(poc); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(ai)); + poc = upb_Atomic_Load(&ai->parent_or_count, memory_order_acquire); + } + + // compare_exchange or fetch_sub are RMW operations, which are more + // expensive then direct loads. As an optimization, we only do RMW ops + // when we need to update things for other threads to see. + if (poc == _upb_Arena_TaggedFromRefcount(1)) { +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogFree(a); +#endif + _upb_Arena_DoFree(ai); + return; + } + + if (upb_Atomic_CompareExchangeWeak( + &ai->parent_or_count, &poc, + _upb_Arena_TaggedFromRefcount(_upb_Arena_RefCountFromTagged(poc) - 1), + memory_order_release, memory_order_acquire)) { + // We were >1 and we decremented it successfully, so we are done. + return; + } + + // We failed our update, so someone has done something, retry the whole + // process, but the failed exchange reloaded `poc` for us. + goto retry; +} + +// Logically performs the following operation, in a way that is safe against +// racing fuses: +// ret = TAIL(parent) +// ret->next = child +// return ret +// +// The caller is therefore guaranteed that ret->next == child. +static upb_ArenaInternal* _upb_Arena_LinkForward( + upb_ArenaInternal* const parent, upb_ArenaInternal* child) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(parent)); + uintptr_t parent_previous_or_tail = + upb_Atomic_Load(&parent->previous_or_tail, memory_order_acquire); + + // Optimization: use parent->previous_or_tail to skip to TAIL(parent) in O(1) + // time when possible. This is the common case because we just fused into + // parent, suggesting that it should be a root with a cached tail. + // + // However, if there was a racing fuse, parent may no longer be a root, in + // which case we need to walk the entire list to find the tail. The tail + // pointer is also not guaranteed to be the true tail, so even when the + // optimization is taken, we still need to walk list nodes to find the true + // tail. + upb_ArenaInternal* parent_tail = + _upb_Arena_IsTaggedTail(parent_previous_or_tail) + ? _upb_Arena_TailFromTagged(parent_previous_or_tail) + : parent; + + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(parent_tail)); + upb_ArenaInternal* parent_tail_next = + upb_Atomic_Load(&parent_tail->next, memory_order_acquire); + + do { + // Walk the list to find the true tail (a node with next == NULL). + while (parent_tail_next != NULL) { + parent_tail = parent_tail_next; + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(parent_tail)); + parent_tail_next = + upb_Atomic_Load(&parent_tail->next, memory_order_acquire); + } + } while (!upb_Atomic_CompareExchangeWeak( // Replace a NULL next with child. + &parent_tail->next, &parent_tail_next, child, memory_order_release, + memory_order_acquire)); + + return parent_tail; +} + +// Updates parent->previous_or_tail = child->previous_or_tail in hopes that the +// latter represents the true tail of the newly-combined list. +// +// This is a best-effort operation that may set the tail to a stale value, and +// may fail to update the tail at all. +void _upb_Arena_UpdateParentTail(upb_ArenaInternal* parent, + upb_ArenaInternal* child) { + // We are guaranteed that child->previous_or_tail is tagged, because we have + // just transitioned child from root -> non-root, which is an exclusive + // operation that can only happen once. So we are the exclusive updater of + // child->previous_or_tail that can transition it from tagged to untagged. + // + // However, we are not guaranteed that child->previous_or_tail is the true + // tail. A racing fuse may have appended to child's list but not yet updated + // child->previous_or_tail. + uintptr_t child_previous_or_tail = + upb_Atomic_Load(&child->previous_or_tail, memory_order_acquire); + upb_ArenaInternal* new_parent_tail = + _upb_Arena_TailFromTagged(child_previous_or_tail); + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(new_parent_tail)); + + // If another thread fused with parent, such that it is no longer a root, + // don't overwrite their previous pointer with our tail. Relaxed order is fine + // here as we only inspect the tag bit. + uintptr_t parent_previous_or_tail = + upb_Atomic_Load(&parent->previous_or_tail, memory_order_relaxed); + if (_upb_Arena_IsTaggedTail(parent_previous_or_tail)) { + upb_Atomic_CompareExchangeStrong( + &parent->previous_or_tail, &parent_previous_or_tail, + _upb_Arena_TaggedFromTail(new_parent_tail), memory_order_release, + memory_order_relaxed); + } +} + +static void _upb_Arena_LinkBackward(upb_ArenaInternal* child, + upb_ArenaInternal* old_parent_tail) { + // Link child to parent going backwards, for SpaceAllocated. This transitions + // child->previous_or_tail from tail (tagged) to previous (untagged), after + // which its value is immutable. + // + // - We are guaranteed that no other threads are also attempting to perform + // this transition (tail -> previous), because we just updated + // old_parent_tail->next from NULL to non-NULL, an exclusive operation that + // can only happen once. + // + // - _upb_Arena_UpdateParentTail() uses CAS to ensure that it + // does not perform the reverse transition (previous -> tail). + // + // - We are guaranteed that old_parent_tail is the correct "previous" pointer, + // even in the presence of racing fuses that are adding more nodes to the + // list, because _upb_Arena_LinkForward() guarantees that: + // old_parent_tail->next == child. + upb_Atomic_Store(&child->previous_or_tail, + _upb_Arena_TaggedFromPrevious(old_parent_tail), + memory_order_release); +} + +static void _upb_Arena_DoFuseArenaLists(upb_ArenaInternal* const parent, + upb_ArenaInternal* child) { + upb_ArenaInternal* old_parent_tail = _upb_Arena_LinkForward(parent, child); + _upb_Arena_UpdateParentTail(parent, child); + _upb_Arena_LinkBackward(child, old_parent_tail); +} + +void upb_Arena_SetAllocCleanup(upb_Arena* a, upb_AllocCleanupFunc* func) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + upb_ArenaInternal* ai = upb_Arena_Internal(a); + UPB_ASSERT(ai->upb_alloc_cleanup == NULL); + ai->upb_alloc_cleanup = func; +} + +// Thread safe. +static upb_ArenaInternal* _upb_Arena_DoFuse(upb_ArenaInternal** ai1, + upb_ArenaInternal** ai2, + uintptr_t* ref_delta) { + // `parent_or_count` has two distinct modes + // - parent pointer mode + // - refcount mode + // + // In parent pointer mode, it may change what pointer it refers to in the + // tree, but it will always approach a root. Any operation that walks the + // tree to the root may collapse levels of the tree concurrently. + upb_ArenaRoot r1 = _upb_Arena_FindRoot(*ai1); + upb_ArenaRoot r2 = _upb_Arena_FindRoot(*ai2); + + if (r1.root == r2.root) return r1.root; // Already fused. + + *ai1 = r1.root; + *ai2 = r2.root; + + // Avoid cycles by always fusing into the root with the lower address. + if ((uintptr_t)r1.root > (uintptr_t)r2.root) { + upb_ArenaRoot tmp = r1; + r1 = r2; + r2 = tmp; + } + + // The moment we install `r1` as the parent for `r2` all racing frees may + // immediately begin decrementing `r1`'s refcount (including pending + // increments to that refcount and their frees!). We need to add `r2`'s refs + // now, so that `r1` can withstand any unrefs that come from r2. + // + // Note that while it is possible for `r2`'s refcount to increase + // asynchronously, we will not actually do the reparenting operation below + // unless `r2`'s refcount is unchanged from when we read it. + // + // Note that we may have done this previously, either to this node or a + // different node, during a previous and failed DoFuse() attempt. But we will + // not lose track of these refs because we always add them to our overall + // delta. + uintptr_t r2_untagged_count = r2.tagged_count & ~1; + uintptr_t with_r2_refs = r1.tagged_count + r2_untagged_count; + if (!upb_Atomic_CompareExchangeStrong( + &r1.root->parent_or_count, &r1.tagged_count, with_r2_refs, + memory_order_release, memory_order_acquire)) { + return NULL; + } + + // Perform the actual fuse by removing the refs from `r2` and swapping in the + // parent pointer. + if (!upb_Atomic_CompareExchangeStrong( + &r2.root->parent_or_count, &r2.tagged_count, + _upb_Arena_TaggedFromPointer(r1.root), memory_order_release, + memory_order_acquire)) { + // We'll need to remove the excess refs we added to r1 previously. + *ref_delta += r2_untagged_count; + return NULL; + } + + // Now that the fuse has been performed (and can no longer fail) we need to + // append `r2` to `r1`'s linked list. + _upb_Arena_DoFuseArenaLists(r1.root, r2.root); + return r1.root; +} + +// Thread safe. +static bool _upb_Arena_FixupRefs(upb_ArenaInternal* new_root, + uintptr_t ref_delta) { + if (ref_delta == 0) return true; // No fixup required. + // Relaxed order is safe here as if the value is a pointer, we don't deref it + // or publish it anywhere else. The refcount does provide memory order + // between allocations on arenas and the eventual free and thus normally + // requires acquire/release; but in this case any edges provided by the refs + // we are cleaning up were already provided by the fuse operation itself. It's + // not valid for a decrement that could cause the overall fused arena to reach + // a zero refcount to race with this function, as that could result in a + // use-after-free anyway. + uintptr_t poc = + upb_Atomic_Load(&new_root->parent_or_count, memory_order_relaxed); + if (_upb_Arena_IsTaggedPointer(poc)) return false; + uintptr_t with_refs = poc - ref_delta; + UPB_ASSERT(!_upb_Arena_IsTaggedPointer(with_refs)); + // Relaxed order on success is safe here, for the same reasons as the relaxed + // read above. Relaxed order is safe on failure because the updated value is + // stored in a local variable which goes immediately out of scope; the retry + // loop will reread what it needs with proper memory order. + return upb_Atomic_CompareExchangeStrong(&new_root->parent_or_count, &poc, + with_refs, memory_order_relaxed, + memory_order_relaxed); +} + +bool upb_Arena_Fuse(const upb_Arena* a1, const upb_Arena* a2) { + if (a1 == a2) return true; // trivial fuse + +#ifdef UPB_TRACING_ENABLED + upb_Arena_LogFuse(a1, a2); +#endif + + upb_ArenaInternal* ai1 = upb_Arena_Internal(a1); + upb_ArenaInternal* ai2 = upb_Arena_Internal(a2); + + // Do not fuse initial blocks since we cannot lifetime extend them. + // Any other fuse scenario is allowed. + if (_upb_ArenaInternal_HasInitialBlock(ai1) || + _upb_ArenaInternal_HasInitialBlock(ai2)) { + return false; + } + + // The number of refs we ultimately need to transfer to the new root. + uintptr_t ref_delta = 0; + while (true) { + upb_ArenaInternal* new_root = _upb_Arena_DoFuse(&ai1, &ai2, &ref_delta); + if (new_root != NULL && _upb_Arena_FixupRefs(new_root, ref_delta)) { +#if UPB_ENABLE_REF_CYCLE_CHECKS + UPB_ASSERT(!upb_Arena_HasRefChain(a1, a2)); +#endif + return true; + } + } +} + +bool upb_Arena_IsFused(const upb_Arena* a, const upb_Arena* b) { + if (a == b) return true; // trivial fuse + upb_ArenaInternal* ra = _upb_Arena_FindRoot(upb_Arena_Internal(a)).root; + upb_ArenaInternal* rb = upb_Arena_Internal(b); + while (true) { + rb = _upb_Arena_FindRoot(rb).root; + if (ra == rb) return true; + upb_ArenaInternal* tmp = _upb_Arena_FindRoot(ra).root; + if (ra == tmp) return false; + // a's root changed since we last checked. Retry. + ra = tmp; + } +} + +bool upb_Arena_IncRefFor(const upb_Arena* a, const void* owner) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + if (_upb_ArenaInternal_HasInitialBlock(ai)) return false; + upb_ArenaRoot r; + r.root = ai; + +retry: + r = _upb_Arena_FindRoot(r.root); + if (upb_Atomic_CompareExchangeWeak( + &r.root->parent_or_count, &r.tagged_count, + _upb_Arena_TaggedFromRefcount( + _upb_Arena_RefCountFromTagged(r.tagged_count) + 1), + // Relaxed order is safe on success, incrementing the refcount + // need not perform any synchronization with the eventual free of the + // arena - that's provided by decrements. + memory_order_relaxed, + // Relaxed order is safe on failure as r.tagged_count is immediately + // overwritten by retrying the find root operation. + memory_order_relaxed)) { + // We incremented it successfully, so we are done. + return true; + } + // We failed update due to parent switching on the arena. + goto retry; +} + +void upb_Arena_DecRefFor(const upb_Arena* a, const void* owner) { + upb_Arena_Free((upb_Arena*)a); +} + +bool upb_Arena_RefArena(upb_Arena* from, const upb_Arena* to) { + UPB_ASSERT(!upb_Arena_IsFused(from, to)); + if (_upb_ArenaInternal_HasInitialBlock(upb_Arena_Internal(to))) { + // We can't increment a ref to `to`, so return early. + return false; + } + + upb_ArenaInternal* ai = upb_Arena_Internal(from); + upb_ArenaRef* ref = upb_Arena_Malloc(from, kUpb_ArenaRefReserve); + + if (!ref) { + return false; + } + + // When 'from' is freed, a ref on 'to' will be released. + // Intentionally ignore return value, since we already check up above if this + // call will succeed. + bool result = upb_Arena_IncRefFor(to, from); + UPB_ASSERT(result); + + // When we add a reference from `from` to `to`, we need to keep track of the + // ref in the `from` arena's linked list of refs. This allows us to + // walk all refs for `from` when `from` is freed, and thus allows us to + // decrement the refcount on `to` when `from` is freed. + ref->prefix.next = ai->blocks; + ref->prefix.size = 0; + ref->arena = to; + ai->blocks = (upb_MemBlock*)ref; + +#ifndef NDEBUG + // Add to the dedicated list of refs. + // This function is not thread-safe from `from`, so a simple load/store is + // sufficient. + ref->next_ref = upb_Atomic_Load(&ai->refs, memory_order_relaxed); + upb_Atomic_Store(&ai->refs, ref, memory_order_release); +#endif + +#if UPB_ENABLE_REF_CYCLE_CHECKS + UPB_ASSERT(!upb_Arena_HasRefChain(to, from)); // Forbid cycles. +#endif + + return true; +} + +#ifndef NDEBUG +bool upb_Arena_HasRef(const upb_Arena* from, const upb_Arena* to) { + const upb_ArenaInternal* ai = upb_Arena_Internal(from); + const upb_ArenaRef* ref = upb_Atomic_Load(&ai->refs, memory_order_acquire); + while (ref != NULL) { + if (upb_Arena_IsFused(ref->arena, to)) { + return true; + } + ref = ref->next_ref; + } + return false; +} +#endif + +upb_alloc* upb_Arena_GetUpbAlloc(upb_Arena* a) { + UPB_PRIVATE(upb_Xsan_AccessReadOnly)(UPB_XSAN(a)); + upb_ArenaInternal* ai = upb_Arena_Internal(a); + return _upb_ArenaInternal_BlockAlloc(ai); +} + +void UPB_PRIVATE(_upb_Arena_SwapIn)(upb_Arena* des, const upb_Arena* src) { + memcpy(des, src, offsetof(upb_ArenaState, body.space_allocated)); + upb_ArenaInternal* desi = upb_Arena_Internal(des); + upb_ArenaInternal* srci = upb_Arena_Internal(src); + uintptr_t new_space_allocated = + upb_Atomic_Load(&srci->space_allocated, memory_order_relaxed); + upb_Atomic_Store(&desi->space_allocated, new_space_allocated, + memory_order_relaxed); +} + +void UPB_PRIVATE(_upb_Arena_SwapOut)(upb_Arena* des, const upb_Arena* src) { + UPB_PRIVATE(_upb_Arena_SwapIn)(des, src); +} + +bool _upb_Arena_WasLastAlloc(struct upb_Arena* a, void* ptr, size_t oldsize) { + upb_ArenaInternal* ai = upb_Arena_Internal(a); + upb_MemBlock* block = ai->blocks; + // Skip any arena refs. + while (block != NULL && block->size == 0) { + block = block->next; + } + if (block == NULL) return false; + char* start = UPB_PTR_AT(block, kUpb_MemblockReserve, char); + return UPB_PRIVATE(upb_Xsan_PtrEq)(ptr, start) && + UPB_PRIVATE(_upb_Arena_AllocSpan)(oldsize) == + block->size - kUpb_MemblockReserve; +} + + + +// Must be last. + +bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* f, + upb_Message* map_entry_message, upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(map_entry_message)); + const upb_MiniTable* map_entry_mini_table = + upb_MiniTable_MapEntrySubMessage(f); + UPB_ASSERT(map_entry_mini_table); + const upb_MiniTableField* map_entry_key_field = + upb_MiniTable_MapKey(map_entry_mini_table); + const upb_MiniTableField* map_entry_value_field = + upb_MiniTable_MapValue(map_entry_mini_table); + // Map key/value cannot have explicit defaults, + // hence assuming a zero default is valid. + upb_MessageValue default_val = upb_MessageValue_Zero(); + upb_MessageValue map_entry_key = + upb_Message_GetField(map_entry_message, map_entry_key_field, default_val); + upb_MessageValue map_entry_value = upb_Message_GetField( + map_entry_message, map_entry_value_field, default_val); + return upb_Map_Set(map, map_entry_key, map_entry_value, arena); +} + + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) { + const int lg2 = UPB_PRIVATE(_upb_CType_SizeLg2)(type); + return UPB_PRIVATE(_upb_Array_New)(a, 4, lg2); +} + +upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { + UPB_ASSERT(i < upb_Array_Size(arr)); + upb_MessageValue ret; + const char* data = upb_Array_DataPtr(arr); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + memcpy(&ret, data + (i << lg2), 1 << lg2); + return ret; +} + +upb_Message* upb_Array_GetMutable(upb_Array* arr, size_t i) { + UPB_ASSERT(i < upb_Array_Size(arr)); + size_t elem_size = sizeof(upb_Message*); + UPB_ASSERT(elem_size == (1 << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr))); + char* data = upb_Array_MutableDataPtr(arr); + upb_Message* ret; + memcpy(&ret, data + (i * elem_size), elem_size); + UPB_ASSERT(!upb_Message_IsFrozen(ret)); + return ret; +} + +void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + UPB_ASSERT(i < upb_Array_Size(arr)); + char* data = upb_Array_MutableDataPtr(arr); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + memcpy(data + (i << lg2), &val, 1 << lg2); +} + +bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + UPB_ASSERT(arena); + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + upb_Array_Set(arr, arr->UPB_PRIVATE(size) - 1, val); + return true; +} + +bool upb_Array_Copy(upb_Array* dst, const upb_Array* src, upb_Arena* arena) { + UPB_ASSERT(dst); + UPB_ASSERT(src); + UPB_ASSERT(!upb_Array_IsFrozen(dst)); + if (dst == src) return true; + size_t len = upb_Array_Size(src); + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) { + return false; + } + if (len == 0) return true; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst); + const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src); + UPB_ASSERT(lg2 == src_lg2); + char* dst_data = upb_Array_MutableDataPtr(dst); + const char* src_data = upb_Array_DataPtr(src); + memcpy(dst_data, src_data, len << lg2); + return true; +} + +bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src, + upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(dst)); + UPB_ASSERT(src); + size_t src_len = upb_Array_Size(src); + if (src_len == 0) return true; + size_t dst_len = upb_Array_Size(dst); + size_t len = dst_len + src_len; + if (UPB_UNLIKELY(len < dst_len)) return false; + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) { + return false; + } + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst); + const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src); + UPB_ASSERT(lg2 == src_lg2); + char* dst_data = upb_Array_MutableDataPtr(dst); + const char* src_data = upb_Array_DataPtr(src); + memcpy(dst_data + (dst_len << lg2), src_data, src_len << lg2); + return true; +} + +void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx, + size_t count) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + char* data = upb_Array_MutableDataPtr(arr); + memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2); +} + +bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, + upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + UPB_ASSERT(arena); + UPB_ASSERT(i <= arr->UPB_PRIVATE(size)); + UPB_ASSERT(count + arr->UPB_PRIVATE(size) >= count); + const size_t oldsize = arr->UPB_PRIVATE(size); + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + count, arena)) { + return false; + } + upb_Array_Move(arr, i + count, i, oldsize - i); + return true; +} + +/* + * i end arr->size + * |------------|XXXXXXXX|--------| + */ +void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + const size_t end = i + count; + UPB_ASSERT(i <= end); + UPB_ASSERT(end <= arr->UPB_PRIVATE(size)); + upb_Array_Move(arr, i, end, arr->UPB_PRIVATE(size) - end); + arr->UPB_PRIVATE(size) -= count; +} + +bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(arr)); + const size_t oldsize = arr->UPB_PRIVATE(size); + if (UPB_UNLIKELY( + !UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, size, arena))) { + return false; + } + const size_t newsize = arr->UPB_PRIVATE(size); + if (newsize > oldsize) { + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); + char* data = upb_Array_MutableDataPtr(arr); + memset(data + (oldsize << lg2), 0, (newsize - oldsize) << lg2); + } + return true; +} + +bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity, + upb_Arena* arena) { + size_t new_capacity = UPB_MAX(array->UPB_PRIVATE(capacity), 4); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); + size_t old_bytes = array->UPB_PRIVATE(capacity) << lg2; + void* ptr = upb_Array_MutableDataPtr(array); + + // Log2 ceiling of size. + while (new_capacity < min_capacity) { + if (upb_ShlOverflow(&new_capacity, 1)) { + new_capacity = SIZE_MAX; + break; + } + } + + size_t new_bytes = new_capacity; + if (upb_ShlOverflow(&new_bytes, lg2)) { + return false; + } + ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes); + if (!ptr) return false; + + UPB_PRIVATE(_upb_Array_SetTaggedPtr)(array, ptr, lg2); + array->UPB_PRIVATE(capacity) = new_capacity; + return true; +} + +void upb_Array_Freeze(upb_Array* arr, const upb_MiniTable* m) { + if (upb_Array_IsFrozen(arr)) return; + UPB_PRIVATE(_upb_Array_ShallowFreeze)(arr); + + if (m) { + const size_t size = upb_Array_Size(arr); + + for (size_t i = 0; i < size; i++) { + upb_MessageValue val = upb_Array_Get(arr, i); + upb_Message_Freeze((upb_Message*)val.msg_val, m); + } + } +} + + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +bool upb_Message_NextExtensionReverse(const upb_Message* msg, + const upb_MiniTableExtension** result, + uintptr_t* iter) { + upb_MessageValue val; + return UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, result, &val, + iter); +} + +const upb_MiniTableExtension* upb_Message_FindExtensionByNumber( + const upb_Message* msg, uint32_t field_number) { + uintptr_t iter = kUpb_Message_ExtensionBegin; + const upb_MiniTableExtension* result; + while (upb_Message_NextExtensionReverse(msg, &result, &iter)) { + if (upb_MiniTableExtension_Number(result) == field_number) return result; + } + return NULL; +} + + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +// Strings/bytes are special-cased in maps. +char _upb_Map_CTypeSizeTable[12] = { + [kUpb_CType_Bool] = 1, + [kUpb_CType_Float] = 4, + [kUpb_CType_Int32] = 4, + [kUpb_CType_UInt32] = 4, + [kUpb_CType_Enum] = 4, + [kUpb_CType_Message] = sizeof(void*), + [kUpb_CType_Double] = 8, + [kUpb_CType_Int64] = 8, + [kUpb_CType_UInt64] = 8, + [kUpb_CType_String] = UPB_MAPTYPE_STRING, + [kUpb_CType_Bytes] = UPB_MAPTYPE_STRING, +}; + +upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, upb_CType value_type) { + return _upb_Map_New(a, _upb_Map_CTypeSize(key_type), + _upb_Map_CTypeSize(value_type)); +} + +size_t upb_Map_Size(const upb_Map* map) { return _upb_Map_Size(map); } + +bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val) { + return _upb_Map_Get(map, &key, map->key_size, val, map->val_size); +} + +struct upb_Message* upb_Map_GetMutable(upb_Map* map, upb_MessageValue key) { + UPB_ASSERT(map->val_size == sizeof(upb_Message*)); + upb_Message* val = NULL; + if (_upb_Map_Get(map, &key, map->key_size, &val, sizeof(upb_Message*))) { + return val; + } else { + return NULL; + } +} + +void upb_Map_Clear(upb_Map* map) { _upb_Map_Clear(map); } + +upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key, + upb_MessageValue val, upb_Arena* arena) { + UPB_ASSERT(arena); + return (upb_MapInsertStatus)_upb_Map_Insert(map, &key, map->key_size, &val, + map->val_size, arena); +} + +bool upb_Map_Delete(upb_Map* map, upb_MessageValue key, upb_MessageValue* val) { + upb_value v; + const bool removed = _upb_Map_Delete(map, &key, map->key_size, &v); + if (val) _upb_map_fromvalue(v, val, map->val_size); + return removed; +} + +bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key, + upb_MessageValue* val, size_t* iter) { + upb_value v; + bool ret; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView strkey; + ret = upb_strtable_next2(&map->t.strtable, &strkey, &v, (intptr_t*)iter); + if (ret) { + _upb_map_fromkey(strkey, key, map->key_size); + } + } else { + uintptr_t intkey; + ret = upb_inttable_next(&map->t.inttable, &intkey, &v, (intptr_t*)iter); + if (ret) { + memcpy(key, &intkey, map->key_size); + } + } + if (ret) { + _upb_map_fromvalue(v, val, map->val_size); + } + return ret; +} + +UPB_API void upb_Map_SetEntryValue(upb_Map* map, size_t iter, + upb_MessageValue val) { + upb_value v; + _upb_map_tovalue(&val, map->val_size, &v, NULL); + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_setentryvalue(&map->t.strtable, iter, v); + } else { + upb_inttable_setentryvalue(&map->t.inttable, iter, v); + } +} + +bool upb_MapIterator_Next(const upb_Map* map, size_t* iter) { + return _upb_map_next(map, iter); +} + +bool upb_MapIterator_Done(const upb_Map* map, size_t iter) { + UPB_ASSERT(iter != kUpb_Map_Begin); + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter i; + i.t = &map->t.strtable; + i.index = iter; + return upb_strtable_done(&i); + } else { + return upb_inttable_done(&map->t.inttable, iter); + } +} + +// Returns the key and value for this entry of the map. +upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter) { + upb_MessageValue ret; + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter i; + i.t = &map->t.strtable; + i.index = iter; + _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size); + } else { + uintptr_t intkey = upb_inttable_iter_key(&map->t.inttable, iter); + memcpy(&ret, &intkey, map->key_size); + } + return ret; +} + +upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter) { + upb_value v; + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter i; + i.t = &map->t.strtable; + i.index = iter; + v = upb_strtable_iter_value(&i); + } else { + v = upb_inttable_iter_value(&map->t.inttable, iter); + } + + upb_MessageValue ret; + _upb_map_fromvalue(v, &ret, map->val_size); + return ret; +} + +void upb_Map_Freeze(upb_Map* map, const upb_MiniTable* m) { + if (upb_Map_IsFrozen(map)) return; + UPB_PRIVATE(_upb_Map_ShallowFreeze)(map); + + if (m) { + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + + while (upb_Map_Next(map, &key, &val, &iter)) { + upb_Message_Freeze((upb_Message*)val.msg_val, m); + } + } +} + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { + upb_Map* map = upb_Arena_Malloc(a, sizeof(upb_Map)); + if (!map) return NULL; + + if (key_size <= sizeof(uintptr_t) && key_size != UPB_MAPTYPE_STRING) { + if (!upb_inttable_init(&map->t.inttable, a)) return NULL; + map->UPB_PRIVATE(is_strtable) = false; + } else { + if (!upb_strtable_init(&map->t.strtable, 4, a)) return NULL; + map->UPB_PRIVATE(is_strtable) = true; + } + map->key_size = key_size; + map->val_size = value_size; + map->UPB_PRIVATE(is_frozen) = false; + + return map; +} + + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Must be last. + +static int _upb_mapsorter_intkeys(const void* _a, const void* _b) { + const upb_tabent* const* a = _a; + const upb_tabent* const* b = _b; + uintptr_t a_key = (*a)->key.num; + uintptr_t b_key = (*b)->key.num; + return a_key < b_key ? -1 : a_key > b_key; +} + +static void _upb_mapsorter_getkeys(const void* _a, const void* _b, void* a_key, + void* b_key, size_t size) { + const upb_tabent* const* a = _a; + const upb_tabent* const* b = _b; + upb_StringView a_tabkey = upb_key_strview((*a)->key); + upb_StringView b_tabkey = upb_key_strview((*b)->key); + _upb_map_fromkey(a_tabkey, a_key, size); + _upb_map_fromkey(b_tabkey, b_key, size); +} + +static int _upb_mapsorter_cmpi64(const void* _a, const void* _b) { + int64_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpu64(const void* _a, const void* _b) { + uint64_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 8); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpi32(const void* _a, const void* _b) { + int32_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpu32(const void* _a, const void* _b) { + uint32_t a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 4); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpbool(const void* _a, const void* _b) { + bool a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, 1); + return a < b ? -1 : a > b; +} + +static int _upb_mapsorter_cmpstr(const void* _a, const void* _b) { + upb_StringView a, b; + _upb_mapsorter_getkeys(_a, _b, &a, &b, UPB_MAPTYPE_STRING); + size_t common_size = UPB_MIN(a.size, b.size); + int cmp = memcmp(a.data, b.data, common_size); + if (cmp) return -cmp; + return a.size < b.size ? -1 : a.size > b.size; +} + +static int (*const compar[kUpb_FieldType_SizeOf])(const void*, const void*) = { + [kUpb_FieldType_Int64] = _upb_mapsorter_cmpi64, + [kUpb_FieldType_SFixed64] = _upb_mapsorter_cmpi64, + [kUpb_FieldType_SInt64] = _upb_mapsorter_cmpi64, + + [kUpb_FieldType_UInt64] = _upb_mapsorter_cmpu64, + [kUpb_FieldType_Fixed64] = _upb_mapsorter_cmpu64, + + [kUpb_FieldType_Int32] = _upb_mapsorter_cmpi32, + [kUpb_FieldType_SInt32] = _upb_mapsorter_cmpi32, + [kUpb_FieldType_SFixed32] = _upb_mapsorter_cmpi32, + [kUpb_FieldType_Enum] = _upb_mapsorter_cmpi32, + + [kUpb_FieldType_UInt32] = _upb_mapsorter_cmpu32, + [kUpb_FieldType_Fixed32] = _upb_mapsorter_cmpu32, + + [kUpb_FieldType_Bool] = _upb_mapsorter_cmpbool, + + [kUpb_FieldType_String] = _upb_mapsorter_cmpstr, + [kUpb_FieldType_Bytes] = _upb_mapsorter_cmpstr, +}; + +static bool _upb_mapsorter_resize(_upb_mapsorter* s, _upb_sortedmap* sorted, + int size) { + sorted->start = s->size; + sorted->pos = sorted->start; + sorted->end = sorted->start + size; + + if (sorted->end > s->cap) { + const int oldsize = s->cap * sizeof(*s->entries); + s->cap = upb_RoundUpToPowerOfTwo(sorted->end); + const int newsize = s->cap * sizeof(*s->entries); + s->entries = upb_grealloc(s->entries, oldsize, newsize); + if (!s->entries) return false; + } + + s->size = sorted->end; + return true; +} + +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const upb_Map* map, _upb_sortedmap* sorted) { + int map_size; + if (map->UPB_PRIVATE(is_strtable)) { + map_size = _upb_Map_Size(map); + } else { + // For inttable, only sort the table entries, since the array part is + // already in a sorted order. + map_size = map->t.inttable.t.count; + } + + if (!_upb_mapsorter_resize(s, sorted, map_size)) return false; + + // Copy non-empty entries from the table to s->entries. + const void** dst = &s->entries[sorted->start]; + const upb_tabent* src; + const upb_tabent* end; + if (map->UPB_PRIVATE(is_strtable)) { + src = map->t.strtable.t.entries; + end = src + upb_table_size(&map->t.strtable.t); + } else { + // For inttable, only sort the table entries, since the array part is + // already in a sorted order. + src = map->t.inttable.t.entries; + end = src + upb_table_size(&map->t.inttable.t); + } + for (; src < end; src++) { + if (!upb_tabent_isempty(src)) { + *dst = src; + dst++; + } + } + UPB_ASSERT(dst == &s->entries[sorted->end]); + + // Sort entries according to the key type. + qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), + map->UPB_PRIVATE(is_strtable) ? compar[key_type] + : _upb_mapsorter_intkeys); + return true; +} + +static int _upb_mapsorter_cmpext(const void* _a, const void* _b) { + const upb_Extension* const* a = _a; + const upb_Extension* const* b = _b; + uint32_t a_num = upb_MiniTableExtension_Number((*a)->ext); + uint32_t b_num = upb_MiniTableExtension_Number((*b)->ext); + UPB_ASSERT(a_num != b_num); + return a_num < b_num ? -1 : 1; +} + +bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, + _upb_sortedmap* sorted) { + size_t count = 0; + for (size_t i = 0; i < in->size; i++) { + count += upb_TaggedAuxPtr_IsExtension(in->aux_data[i]); + } + if (!_upb_mapsorter_resize(s, sorted, count)) return false; + if (count == 0) return true; + const upb_Extension** entry = + (const upb_Extension**)&s->entries[sorted->start]; + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + *entry++ = upb_TaggedAuxPtr_Extension(tagged_ptr); + } + } + qsort(&s->entries[sorted->start], count, sizeof(*s->entries), + _upb_mapsorter_cmpext); + return true; +} + + +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* a) { + return _upb_Message_New(m, a); +} + +UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg, + const char* data, + size_t len, + upb_Arena* arena, + bool alias) { + { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + // Alias fast path was already checked in the inline function that calls + // this one + if (!alias && in && in->size) { + upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1]; + if (upb_TaggedAuxPtr_IsUnknown(ptr)) { + upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr); + if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) { + // If part of the existing field was deleted at the beginning, we can + // reconstruct it by comparing the address of the end with the address + // of the entry itself; having the non-aliased tag means that the + // string_view and the data it points to are part of the same original + // upb_Arena_Malloc allocation, and the end of the string view + // represents the end of that allocation. + size_t prev_alloc_size = + (existing->data + existing->size) - (char*)existing; + if (SIZE_MAX - prev_alloc_size >= len) { + size_t new_alloc_size = prev_alloc_size + len; + if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, + new_alloc_size)) { + memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len); + existing->size += len; + return true; + } + } + } + } + } + } + // TODO: b/376969853 - Add debug check that the unknown field is an overall + // valid proto field + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { + return false; + } + upb_StringView* view; + if (alias) { + view = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!view) return false; + view->data = data; + } else { + if (SIZE_MAX - sizeof(upb_StringView) < len) return false; + view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); + if (!view) return false; + char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); + memcpy(copy, data, len); + view->data = copy; + } + view->size = len; + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + in->aux_data[in->size++] = alias + ? upb_TaggedAuxPtr_MakeUnknownDataAliased(view) + : upb_TaggedAuxPtr_MakeUnknownData(view); + return true; +} + +bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, + upb_Arena* arena, + upb_StringView data[], + size_t count) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(count > 0); + size_t total_len = 0; + for (size_t i = 0; i < count; i++) { + if (SIZE_MAX - total_len < data[i].size) { + return false; + } + total_len += data[i].size; + } + + { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (in && in->size) { + upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1]; + if (upb_TaggedAuxPtr_IsUnknown(ptr)) { + upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr); + if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) { + size_t prev_alloc_size = + (existing->data + existing->size) - (char*)existing; + if (SIZE_MAX - prev_alloc_size >= total_len) { + size_t new_alloc_size = prev_alloc_size + total_len; + if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, + new_alloc_size)) { + char* copy = UPB_PTR_AT(existing, prev_alloc_size, char); + for (size_t i = 0; i < count; i++) { + memcpy(copy, data[i].data, data[i].size); + copy += data[i].size; + } + existing->size += total_len; + return true; + } + } + } + } + } + } + + if (SIZE_MAX - sizeof(upb_StringView) < total_len) return false; + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false; + + upb_StringView* view = + upb_Arena_Malloc(arena, sizeof(upb_StringView) + total_len); + if (!view) return false; + char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); + view->data = copy; + view->size = total_len; + for (size_t i = 0; i < count; i++) { + memcpy(copy, data[i].data, data[i].size); + copy += data[i].size; + } + // TODO: b/376969853 - Add debug check that the unknown field is an overall + // valid proto field + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeUnknownData(view); + return true; +} + +void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return; + uint32_t size = 0; + for (uint32_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + in->aux_data[size++] = tagged_ptr; + } + } + in->size = size; +} + +upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg, + upb_StringView* data, + uintptr_t* iter, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(*iter != kUpb_Message_UnknownBegin); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + UPB_ASSERT(in); + UPB_ASSERT(*iter <= in->size); + upb_TaggedAuxPtr unknown_ptr = in->aux_data[*iter - 1]; + UPB_ASSERT(upb_TaggedAuxPtr_IsUnknown(unknown_ptr)); + upb_StringView* unknown = upb_TaggedAuxPtr_UnknownData(unknown_ptr); + if (unknown->data == data->data && unknown->size == data->size) { + // Remove whole field + in->aux_data[*iter - 1] = upb_TaggedAuxPtr_Null(); + } else if (unknown->data == data->data) { + // Strip prefix + unknown->data += data->size; + unknown->size -= data->size; + *data = *unknown; + return kUpb_DeleteUnknown_IterUpdated; + } else if (unknown->data + unknown->size == data->data + data->size) { + // Truncate existing field + unknown->size -= data->size; + if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) { + in->aux_data[*iter - 1] = + upb_TaggedAuxPtr_MakeUnknownDataAliased(unknown); + } + } else { + UPB_ASSERT(unknown->data < data->data && + unknown->data + unknown->size > data->data + data->size); + // Split in the middle + upb_StringView* prefix = unknown; + upb_StringView* suffix = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!suffix) { + return kUpb_DeleteUnknown_AllocFail; + } + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) { + return kUpb_DeleteUnknown_AllocFail; + } + in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (*iter != in->size) { + // Shift later entries down so that unknown field ordering is preserved + memmove(&in->aux_data[*iter + 1], &in->aux_data[*iter], + sizeof(upb_TaggedAuxPtr) * (in->size - *iter)); + } + in->aux_data[*iter] = upb_TaggedAuxPtr_MakeUnknownDataAliased(suffix); + if (!upb_TaggedAuxPtr_IsUnknownAliased(unknown_ptr)) { + in->aux_data[*iter - 1] = upb_TaggedAuxPtr_MakeUnknownDataAliased(prefix); + } + in->size++; + suffix->data = data->data + data->size; + suffix->size = (prefix->data + prefix->size) - suffix->data; + prefix->size = data->data - prefix->data; + } + return upb_Message_NextUnknown(msg, data, iter) + ? kUpb_DeleteUnknown_IterUpdated + : kUpb_DeleteUnknown_DeletedLast; +} + +size_t upb_Message_ExtensionCount(const upb_Message* msg) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return 0; + const upb_MiniTableExtension* ext; + upb_MessageValue val; + uintptr_t iter = kUpb_Message_ExtensionBegin; + size_t count = 0; + while (upb_Message_NextExtension(msg, &ext, &val, &iter)) { + count++; + } + return count; +} + +void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { + if (upb_Message_IsFrozen(msg)) return; + UPB_PRIVATE(_upb_Message_ShallowFreeze)(msg); + + // Base Fields. + const size_t field_count = upb_MiniTable_FieldCount(m); + + for (size_t i = 0; i < field_count; i++) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + const upb_MiniTable* m2 = upb_MiniTable_SubMessage(f); + + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) { + case kUpb_FieldMode_Array: { + upb_Array* arr = upb_Message_GetMutableArray(msg, f); + if (arr) upb_Array_Freeze(arr, m2); + break; + } + case kUpb_FieldMode_Map: { + upb_Map* map = upb_Message_GetMutableMap(msg, f); + if (map) { + const upb_MiniTableField* f2 = upb_MiniTable_MapValue(m2); + const upb_MiniTable* m3 = upb_MiniTable_SubMessage(f2); + upb_Map_Freeze(map, m3); + } + break; + } + case kUpb_FieldMode_Scalar: { + if (m2) { + upb_Message* msg2 = upb_Message_GetMutableMessage(msg, f); + if (msg2) upb_Message_Freeze(msg2, m2); + } + break; + } + } + } + + // Extensions. + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + // TODO: b/376969853 - use iterator API + uint32_t size = in ? in->size : 0; + for (size_t i = 0; i < size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (!upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + continue; + } + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + const upb_MiniTableExtension* e = ext->ext; + const upb_MiniTableField* f = &e->UPB_PRIVATE(field); + const upb_MiniTable* m2 = upb_MiniTableExtension_GetSubMessage(e); + + upb_MessageValue val; + memcpy(&val, &(ext->data), sizeof(upb_MessageValue)); + + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) { + case kUpb_FieldMode_Array: { + upb_Array* arr = (upb_Array*)val.array_val; + if (arr) upb_Array_Freeze(arr, m2); + break; + } + case kUpb_FieldMode_Map: + UPB_UNREACHABLE(); // Maps cannot be extensions. + break; + case kUpb_FieldMode_Scalar: + if (upb_MiniTableField_IsSubMessage(f)) { + upb_Message* msg2 = (upb_Message*)val.msg_val; + if (msg2) upb_Message_Freeze(msg2, m2); + } + break; + } + } +} + + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_Message_IsEmpty(const upb_Message* msg, const upb_MiniTable* m) { + if (upb_Message_ExtensionCount(msg)) return false; + + const upb_MiniTableField* f; + upb_MessageValue v; + size_t iter = kUpb_BaseField_Begin; + return !UPB_PRIVATE(_upb_Message_NextBaseField)(msg, m, &f, &v, &iter); +} + +static bool _upb_Array_IsEqual(const upb_Array* arr1, const upb_Array* arr2, + upb_CType ctype, const upb_MiniTable* m, + int options) { + // Check for trivial equality. + if (arr1 == arr2) return true; + + // Must have identical element counts. + const size_t size1 = arr1 ? upb_Array_Size(arr1) : 0; + const size_t size2 = arr2 ? upb_Array_Size(arr2) : 0; + if (size1 != size2) return false; + + for (size_t i = 0; i < size1; i++) { + const upb_MessageValue val1 = upb_Array_Get(arr1, i); + const upb_MessageValue val2 = upb_Array_Get(arr2, i); + + if (!upb_MessageValue_IsEqual(val1, val2, ctype, m, options)) return false; + } + + return true; +} + +static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, + const upb_MiniTable* m, int options) { + // Check for trivial equality. + if (map1 == map2) return true; + + // Must have identical element counts. + size_t size1 = map1 ? upb_Map_Size(map1) : 0; + size_t size2 = map2 ? upb_Map_Size(map2) : 0; + if (size1 != size2) return false; + + const upb_MiniTableField* f = upb_MiniTable_MapValue(m); + const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f); + const upb_CType ctype = upb_MiniTableField_CType(f); + + upb_MessageValue key, val1, val2; + size_t iter = kUpb_Map_Begin; + while (upb_Map_Next(map1, &key, &val1, &iter)) { + if (!upb_Map_Get(map2, key, &val2)) return false; + if (!upb_MessageValue_IsEqual(val1, val2, ctype, m2_value, options)) + return false; + } + + return true; +} + +static bool _upb_Message_BaseFieldsAreEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, + int options) { + // Iterate over all base fields for each message. + // The order will always match if the messages are equal. + size_t iter1 = kUpb_BaseField_Begin; + size_t iter2 = kUpb_BaseField_Begin; + + for (;;) { + const upb_MiniTableField *f1, *f2; + upb_MessageValue val1, val2; + + const bool got1 = + UPB_PRIVATE(_upb_Message_NextBaseField)(msg1, m, &f1, &val1, &iter1); + const bool got2 = + UPB_PRIVATE(_upb_Message_NextBaseField)(msg2, m, &f2, &val2, &iter2); + + if (got1 != got2) return false; // Must have identical field counts. + if (!got1) return true; // Loop termination condition. + if (f1 != f2) return false; // Must have identical fields set. + + const upb_MiniTable* subm = upb_MiniTable_SubMessage(f1); + const upb_CType ctype = upb_MiniTableField_CType(f1); + + bool eq; + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f1)) { + case kUpb_FieldMode_Array: + eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm, + options); + break; + case kUpb_FieldMode_Map: + eq = _upb_Map_IsEqual(val1.map_val, val2.map_val, subm, options); + break; + case kUpb_FieldMode_Scalar: + eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options); + break; + } + if (!eq) return false; + } +} + +static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, + int options) { + const upb_MiniTableExtension* e; + upb_MessageValue val1; + + // Iterate over all extensions for msg1, and search msg2 for each extension. + size_t count1 = 0; + size_t iter1 = kUpb_Message_ExtensionBegin; + while (upb_Message_NextExtension(msg1, &e, &val1, &iter1)) { + const upb_Extension* ext2 = UPB_PRIVATE(_upb_Message_Getext)(msg2, e); + if (!ext2) return false; + + count1++; + + const upb_MessageValue val2 = ext2->data; + const upb_MiniTableField* f = &e->UPB_PRIVATE(field); + const upb_MiniTable* subm = upb_MiniTableField_IsSubMessage(f) + ? upb_MiniTableExtension_GetSubMessage(e) + : NULL; + const upb_CType ctype = upb_MiniTableField_CType(f); + + bool eq; + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) { + case kUpb_FieldMode_Array: + eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm, + options); + break; + case kUpb_FieldMode_Map: + UPB_UNREACHABLE(); // Maps cannot be extensions. + break; + case kUpb_FieldMode_Scalar: { + eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options); + break; + } + } + if (!eq) return false; + } + + // Must have identical extension counts (this catches the case where msg2 + // has extensions that msg1 doesn't). + if (count1 != upb_Message_ExtensionCount(msg2)) return false; + + return true; +} + +bool upb_Message_IsEqual(const upb_Message* msg1, const upb_Message* msg2, + const upb_MiniTable* m, int options) { + if (UPB_UNLIKELY(msg1 == msg2)) return true; + + if (!_upb_Message_BaseFieldsAreEqual(msg1, msg2, m, options)) return false; + if (!_upb_Message_ExtensionsAreEqual(msg1, msg2, m, options)) return false; + + if (!(options & kUpb_CompareOption_IncludeUnknownFields)) return true; + + // The wire encoder enforces a maximum depth of 100 so we match that here. + return UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)(msg1, msg2, 100) == + kUpb_UnknownCompareResult_Equal; +} + + +#include <stdint.h> +#include <stdlib.h> + + +// Must be last. + +typedef struct upb_UnknownFields upb_UnknownFields; + +typedef struct { + uint32_t tag; + union { + uint64_t varint; + uint64_t uint64; + uint32_t uint32; + upb_StringView delimited; + upb_UnknownFields* group; + } data; +} upb_UnknownField; + +struct upb_UnknownFields { + size_t size; + size_t capacity; + upb_UnknownField* fields; +}; + +typedef struct { + upb_EpsCopyInputStream stream; + upb_Arena* arena; + upb_UnknownField* tmp; + size_t tmp_size; + int depth; + upb_UnknownCompareResult status; + jmp_buf err; +} upb_UnknownField_Context; + +typedef struct { + upb_UnknownField* arr_base; + upb_UnknownField* arr_ptr; + upb_UnknownField* arr_end; + uint32_t last_tag; + bool sorted; +} upb_UnknownFields_Builder; + +UPB_NORETURN static void upb_UnknownFields_OutOfMemory( + upb_UnknownField_Context* ctx) { + ctx->status = kUpb_UnknownCompareResult_OutOfMemory; + UPB_LONGJMP(ctx->err, 1); +} + +static void upb_UnknownFields_Grow(upb_UnknownField_Context* ctx, + upb_UnknownField** base, + upb_UnknownField** ptr, + upb_UnknownField** end) { + size_t old = (*ptr - *base); + size_t new = UPB_MAX(4, old * 2); + + *base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), + new * sizeof(**base)); + if (!*base) upb_UnknownFields_OutOfMemory(ctx); + + *ptr = *base + old; + *end = *base + new; +} + +// We have to implement our own sort here, since qsort() is not an in-order +// sort. Here we use merge sort, the simplest in-order sort. +static void upb_UnknownFields_Merge(upb_UnknownField* arr, size_t start, + size_t mid, size_t end, + upb_UnknownField* tmp) { + memcpy(tmp, &arr[start], (end - start) * sizeof(*tmp)); + + upb_UnknownField* ptr1 = tmp; + upb_UnknownField* end1 = &tmp[mid - start]; + upb_UnknownField* ptr2 = &tmp[mid - start]; + upb_UnknownField* end2 = &tmp[end - start]; + upb_UnknownField* out = &arr[start]; + + while (ptr1 < end1 && ptr2 < end2) { + if (ptr1->tag <= ptr2->tag) { + *out++ = *ptr1++; + } else { + *out++ = *ptr2++; + } + } + + if (ptr1 < end1) { + memcpy(out, ptr1, (end1 - ptr1) * sizeof(*out)); + } else if (ptr2 < end2) { + memcpy(out, ptr1, (end2 - ptr2) * sizeof(*out)); + } +} + +static void upb_UnknownFields_SortRecursive(upb_UnknownField* arr, size_t start, + size_t end, upb_UnknownField* tmp) { + if (end - start > 1) { + size_t mid = start + ((end - start) / 2); + upb_UnknownFields_SortRecursive(arr, start, mid, tmp); + upb_UnknownFields_SortRecursive(arr, mid, end, tmp); + upb_UnknownFields_Merge(arr, start, mid, end, tmp); + } +} + +static void upb_UnknownFields_Sort(upb_UnknownField_Context* ctx, + upb_UnknownFields* fields) { + if (ctx->tmp_size < fields->size) { + const int oldsize = ctx->tmp_size * sizeof(*ctx->tmp); + ctx->tmp_size = UPB_MAX(8, ctx->tmp_size); + while (ctx->tmp_size < fields->size) ctx->tmp_size *= 2; + const int newsize = ctx->tmp_size * sizeof(*ctx->tmp); + ctx->tmp = upb_grealloc(ctx->tmp, oldsize, newsize); + } + upb_UnknownFields_SortRecursive(fields->fields, 0, fields->size, ctx->tmp); +} + +static upb_UnknownFields* upb_UnknownFields_BuildFromBuffer( + upb_UnknownField_Context* ctx, const char** buf); + +// Combines two unknown fields into one. +static void upb_CombineUnknownFields(upb_UnknownField_Context* ctx, + upb_UnknownFields_Builder* builder, + const char** buf) { + upb_UnknownField* arr_base = builder->arr_base; + upb_UnknownField* arr_ptr = builder->arr_ptr; + upb_UnknownField* arr_end = builder->arr_end; + const char* ptr = *buf; + uint32_t last_tag = builder->last_tag; + bool sorted = builder->sorted; + + // Parse the unknown field data. It is an invariant of the data structure that + // unknown field data is valid, so parse errors here should be impossible. + while (!upb_EpsCopyInputStream_IsDone(&ctx->stream, &ptr)) { + uint32_t tag; + ptr = upb_WireReader_ReadTag(ptr, &tag, &ctx->stream); + UPB_ASSERT(tag <= UINT32_MAX); + int wire_type = upb_WireReader_GetWireType(tag); + if (wire_type == kUpb_WireType_EndGroup) break; + if (tag < last_tag) sorted = false; + last_tag = tag; + + if (arr_ptr == arr_end) { + upb_UnknownFields_Grow(ctx, &arr_base, &arr_ptr, &arr_end); + } + upb_UnknownField* field = arr_ptr; + field->tag = tag; + arr_ptr++; + + switch (wire_type) { + case kUpb_WireType_Varint: + ptr = upb_WireReader_ReadVarint(ptr, &field->data.varint, &ctx->stream); + UPB_ASSERT(ptr); + break; + case kUpb_WireType_64Bit: + ptr = + upb_WireReader_ReadFixed64(ptr, &field->data.uint64, &ctx->stream); + UPB_ASSERT(ptr); + break; + case kUpb_WireType_32Bit: + ptr = + upb_WireReader_ReadFixed32(ptr, &field->data.uint32, &ctx->stream); + UPB_ASSERT(ptr); + break; + case kUpb_WireType_Delimited: { + int size; + upb_StringView sv; + ptr = upb_WireReader_ReadSize(ptr, &size, &ctx->stream); + UPB_ASSERT(ptr); + ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(&ctx->stream, ptr, + size, &sv); + UPB_ASSERT(ptr); + field->data.delimited.data = sv.data; + field->data.delimited.size = sv.size; + break; + } + case kUpb_WireType_StartGroup: + if (--ctx->depth < 0) { + ctx->status = kUpb_UnknownCompareResult_MaxDepthExceeded; + UPB_LONGJMP(ctx->err, 1); + } + field->data.group = upb_UnknownFields_BuildFromBuffer(ctx, &ptr); + ctx->depth++; + break; + default: + UPB_UNREACHABLE(); + } + } + *buf = ptr; + builder->arr_base = arr_base; + builder->arr_ptr = arr_ptr; + builder->arr_end = arr_end; + builder->sorted = sorted; + builder->last_tag = last_tag; +} + +static upb_UnknownFields* upb_UnknownFields_DoBuild( + upb_UnknownField_Context* ctx, upb_UnknownFields_Builder* builder) { + upb_UnknownFields* ret = upb_Arena_Malloc(ctx->arena, sizeof(*ret)); + if (!ret) upb_UnknownFields_OutOfMemory(ctx); + ret->fields = builder->arr_base; + ret->size = builder->arr_ptr - builder->arr_base; + ret->capacity = builder->arr_end - builder->arr_base; + if (!builder->sorted) { + upb_UnknownFields_Sort(ctx, ret); + } + return ret; +} + +// Builds a upb_UnknownFields data structure from the binary data in buf. +static upb_UnknownFields* upb_UnknownFields_BuildFromBuffer( + upb_UnknownField_Context* ctx, const char** buf) { + upb_UnknownFields_Builder builder = { + .arr_base = NULL, + .arr_ptr = NULL, + .arr_end = NULL, + .sorted = true, + .last_tag = 0, + }; + const char* ptr = *buf; + upb_CombineUnknownFields(ctx, &builder, &ptr); + upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder); + *buf = ptr; + return fields; +} + +// Builds a upb_UnknownFields data structure from the unknown fields of a +// upb_Message. +static upb_UnknownFields* upb_UnknownFields_Build(upb_UnknownField_Context* ctx, + const upb_Message* msg) { + upb_UnknownFields_Builder builder = { + .arr_base = NULL, + .arr_ptr = NULL, + .arr_end = NULL, + .sorted = true, + .last_tag = 0, + }; + uintptr_t iter = kUpb_Message_UnknownBegin; + upb_StringView view; + while (upb_Message_NextUnknown(msg, &view, &iter)) { + upb_EpsCopyInputStream_Init(&ctx->stream, &view.data, view.size); + upb_CombineUnknownFields(ctx, &builder, &view.data); + UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &view.data) && + !upb_EpsCopyInputStream_IsError(&ctx->stream)); + } + upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder); + return fields; +} + +// Compares two sorted upb_UnknownFields structures for equality. +static bool upb_UnknownFields_IsEqual(const upb_UnknownFields* uf1, + const upb_UnknownFields* uf2) { + if (uf1->size != uf2->size) return false; + for (size_t i = 0, n = uf1->size; i < n; i++) { + upb_UnknownField* f1 = &uf1->fields[i]; + upb_UnknownField* f2 = &uf2->fields[i]; + if (f1->tag != f2->tag) return false; + int wire_type = f1->tag & 7; + switch (wire_type) { + case kUpb_WireType_Varint: + if (f1->data.varint != f2->data.varint) return false; + break; + case kUpb_WireType_64Bit: + if (f1->data.uint64 != f2->data.uint64) return false; + break; + case kUpb_WireType_32Bit: + if (f1->data.uint32 != f2->data.uint32) return false; + break; + case kUpb_WireType_Delimited: + if (!upb_StringView_IsEqual(f1->data.delimited, f2->data.delimited)) { + return false; + } + break; + case kUpb_WireType_StartGroup: + if (!upb_UnknownFields_IsEqual(f1->data.group, f2->data.group)) { + return false; + } + break; + default: + UPB_UNREACHABLE(); + } + } + return true; +} + +static upb_UnknownCompareResult upb_UnknownField_DoCompare( + upb_UnknownField_Context* ctx, const upb_Message* msg1, + const upb_Message* msg2) { + upb_UnknownCompareResult ret; + // First build both unknown fields into a sorted data structure (similar + // to the UnknownFieldSet in C++). + upb_UnknownFields* uf1 = upb_UnknownFields_Build(ctx, msg1); + upb_UnknownFields* uf2 = upb_UnknownFields_Build(ctx, msg2); + + // Now perform the equality check on the sorted structures. + if (upb_UnknownFields_IsEqual(uf1, uf2)) { + ret = kUpb_UnknownCompareResult_Equal; + } else { + ret = kUpb_UnknownCompareResult_NotEqual; + } + return ret; +} + +static upb_UnknownCompareResult upb_UnknownField_Compare( + upb_UnknownField_Context* const ctx, const upb_Message* msg1, + const upb_Message* msg2) { + upb_UnknownCompareResult ret; + if (UPB_SETJMP(ctx->err) == 0) { + ret = upb_UnknownField_DoCompare(ctx, msg1, msg2); + } else { + ret = ctx->status; + UPB_ASSERT(ret != kUpb_UnknownCompareResult_Equal); + } + + upb_Arena_Free(ctx->arena); + upb_gfree(ctx->tmp); + return ret; +} + +upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( + const upb_Message* msg1, const upb_Message* msg2, int max_depth) { + bool msg1_empty = !upb_Message_HasUnknown(msg1); + bool msg2_empty = !upb_Message_HasUnknown(msg2); + if (msg1_empty && msg2_empty) return kUpb_UnknownCompareResult_Equal; + if (msg1_empty || msg2_empty) return kUpb_UnknownCompareResult_NotEqual; + + upb_UnknownField_Context ctx = { + .arena = upb_Arena_New(), + .depth = max_depth, + .tmp = NULL, + .tmp_size = 0, + .status = kUpb_UnknownCompareResult_Equal, + }; + + if (!ctx.arena) return kUpb_UnknownCompareResult_OutOfMemory; + + return upb_UnknownField_Compare(&ctx, msg1, msg2); +} + + +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +static upb_StringView upb_Clone_StringView(upb_StringView str, + upb_Arena* arena) { + if (str.size == 0) { + return upb_StringView_FromDataAndSize(NULL, 0); + } + void* cloned_data = upb_Arena_Malloc(arena, str.size); + upb_StringView cloned_str = + upb_StringView_FromDataAndSize(cloned_data, str.size); + memcpy(cloned_data, str.data, str.size); + return cloned_str; +} + +static bool upb_Clone_MessageValue(void* value, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + switch (value_type) { + case kUpb_CType_Bool: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return true; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView source = *(upb_StringView*)value; + size_t size = source.size; + void* cloned_data = upb_Arena_Malloc(arena, size); + if (cloned_data == NULL) { + return false; + } + *(upb_StringView*)value = + upb_StringView_FromDataAndSize(cloned_data, size); + memcpy(cloned_data, source.data, size); + return true; + } break; + case kUpb_CType_Message: { + UPB_ASSERT(sub); + const upb_Message* source = *(upb_Message**)value; + UPB_ASSERT(source); + upb_Message* clone = upb_Message_DeepClone(source, sub, arena); + *(upb_Message**)value = clone; + return clone != NULL; + } break; + } + UPB_UNREACHABLE(); +} + +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena) { + upb_Map* cloned_map = _upb_Map_New(arena, map->key_size, map->val_size); + if (cloned_map == NULL) { + return NULL; + } + upb_MessageValue key, val; + size_t iter = kUpb_Map_Begin; + while (upb_Map_Next(map, &key, &val, &iter)) { + const upb_MiniTableField* value_field = + upb_MiniTable_MapValue(map_entry_table); + const upb_MiniTable* value_sub = + upb_MiniTableField_CType(value_field) == kUpb_CType_Message + ? upb_MiniTable_GetSubMessageTable(value_field) + : NULL; + upb_CType value_field_type = upb_MiniTableField_CType(value_field); + if (!upb_Clone_MessageValue(&val, value_field_type, value_sub, arena)) { + return NULL; + } + if (!upb_Map_Set(cloned_map, key, val, arena)) { + return NULL; + } + } + return cloned_map; +} + +static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, + const upb_MiniTable* mini_table, + const upb_MiniTableField* f, + upb_Message* clone, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(clone)); + const upb_MiniTable* map_entry_table = upb_MiniTable_MapEntrySubMessage(f); + UPB_ASSERT(map_entry_table); + + const upb_MiniTableField* key_field = upb_MiniTable_MapKey(map_entry_table); + const upb_MiniTableField* value_field = + upb_MiniTable_MapValue(map_entry_table); + + upb_Map* cloned_map = upb_Map_DeepClone( + map, upb_MiniTableField_CType(key_field), + upb_MiniTableField_CType(value_field), map_entry_table, arena); + if (!cloned_map) { + return NULL; + } + upb_Message_SetBaseField(clone, f, &cloned_map); + return cloned_map; +} + +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + const size_t size = upb_Array_Size(array); + const int lg2 = UPB_PRIVATE(_upb_CType_SizeLg2)(value_type); + upb_Array* cloned_array = UPB_PRIVATE(_upb_Array_New)(arena, size, lg2); + if (!cloned_array) { + return NULL; + } + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(cloned_array, size, arena)) { + return NULL; + } + for (size_t i = 0; i < size; ++i) { + upb_MessageValue val = upb_Array_Get(array, i); + if (!upb_Clone_MessageValue(&val, value_type, sub, arena)) { + return NULL; + } + upb_Array_Set(cloned_array, i, val); + } + return cloned_array; +} + +static bool upb_Message_Array_DeepClone(const upb_Array* array, + const upb_MiniTable* mini_table, + const upb_MiniTableField* field, + upb_Message* clone, upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(clone)); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); + upb_Array* cloned_array = + upb_Array_DeepClone(array, upb_MiniTableField_CType(field), + upb_MiniTableField_CType(field) == kUpb_CType_Message + ? upb_MiniTable_GetSubMessageTable(field) + : NULL, + arena); + + // Clear out upb_Array* due to parent memcpy. + upb_Message_SetBaseField(clone, field, &cloned_array); + return true; +} + +static bool upb_Clone_ExtensionValue( + const upb_MiniTableExtension* mini_table_ext, const upb_Extension* source, + upb_Extension* dest, upb_Arena* arena) { + dest->data = source->data; + return upb_Clone_MessageValue( + &dest->data, upb_MiniTableExtension_CType(mini_table_ext), + upb_MiniTableExtension_GetSubMessage(mini_table_ext), arena); +} + +upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(dst)); + upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0); + // Only copy message area skipping upb_Message_Internal. + memcpy(dst + 1, src + 1, mini_table->UPB_PRIVATE(size) - sizeof(upb_Message)); + for (int i = 0; i < upb_MiniTable_FieldCount(mini_table); ++i) { + const upb_MiniTableField* field = + upb_MiniTable_GetFieldByIndex(mini_table, i); + if (upb_MiniTableField_IsScalar(field)) { + switch (upb_MiniTableField_CType(field)) { + case kUpb_CType_Message: { + const upb_Message* sub_message = upb_Message_GetMessage(src, field); + if (sub_message != NULL) { + const upb_MiniTable* sub_message_table = + upb_MiniTable_GetSubMessageTable(field); + upb_Message* dst_sub_message = + upb_Message_DeepClone(sub_message, sub_message_table, arena); + if (dst_sub_message == NULL) { + return NULL; + } + upb_Message_SetBaseFieldMessage(dst, field, dst_sub_message); + } + } break; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView str = upb_Message_GetString(src, field, empty_string); + if (str.size != 0) { + if (!upb_Message_SetString( + dst, field, upb_Clone_StringView(str, arena), arena)) { + return NULL; + } + } + } break; + default: + // Scalar, already copied. + break; + } + } else { + if (upb_MiniTableField_IsMap(field)) { + const upb_Map* map = upb_Message_GetMap(src, field); + if (map != NULL) { + if (!upb_Message_Map_DeepClone(map, mini_table, field, dst, arena)) { + return NULL; + } + } + } else { + const upb_Array* array = upb_Message_GetArray(src, field); + if (array != NULL) { + if (!upb_Message_Array_DeepClone(array, mini_table, field, dst, + arena)) { + return NULL; + } + } + } + } + } + // Clone extensions. + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(src); + if (!in) return dst; + + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + // Clone extension + const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + const upb_MiniTableField* field = &msg_ext->ext->UPB_PRIVATE(field); + upb_Extension* dst_ext = UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + dst, msg_ext->ext, arena); + if (!dst_ext) return NULL; + if (upb_MiniTableField_IsScalar(field)) { + if (!upb_Clone_ExtensionValue(msg_ext->ext, msg_ext, dst_ext, arena)) { + return NULL; + } + } else { + upb_Array* msg_array = (upb_Array*)msg_ext->data.array_val; + UPB_ASSERT(msg_array); + upb_Array* cloned_array = upb_Array_DeepClone( + msg_array, upb_MiniTableField_CType(field), + upb_MiniTableExtension_GetSubMessage(msg_ext->ext), arena); + if (!cloned_array) { + return NULL; + } + dst_ext->data.array_val = cloned_array; + } + } else if (upb_TaggedAuxPtr_IsUnknown(tagged_ptr)) { + // Clone unknown + upb_StringView* unknown = upb_TaggedAuxPtr_UnknownData(tagged_ptr); + // Make a copy into destination arena. + if (!UPB_PRIVATE(_upb_Message_AddUnknown)( + dst, unknown->data, unknown->size, arena, kUpb_AddUnknown_Copy)) { + return NULL; + } + } + } + + return dst; +} + +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(dst)); + upb_Message_Clear(dst, mini_table); + return _upb_Message_Copy(dst, src, mini_table, arena) != NULL; +} + +// Deep clones a message using the provided target arena. +// +// Returns NULL on failure. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + return _upb_Message_Copy(clone, msg, m, arena); +} + +// Performs a shallow copy. TODO: Extend to handle unknown fields. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m) { + UPB_ASSERT(!upb_Message_IsFrozen(dst)); + memcpy(dst, src, m->UPB_PRIVATE(size)); +} + +// Performs a shallow clone. Ignores unknown fields. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, + upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + upb_Message_ShallowCopy(clone, msg, m); + return clone; +} + +#include "stddef.h" + +// Must be last. + +bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + upb_Arena* arena) { + char* buf = NULL; + size_t size = 0; + // This tmp arena is used to hold the bytes for `src` serialized. This bends + // the typical "no hidden allocations" design of upb, but under a properly + // optimized implementation this extra allocation would not be necessary and + // so we don't want to unnecessarily have the bad API or bloat the passed-in + // arena with this very-short-term allocation. + upb_Arena* encode_arena = upb_Arena_New(); + upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size); + if (e_status != kUpb_EncodeStatus_Ok) { + upb_Arena_Free(encode_arena); + return false; + } + upb_DecodeStatus d_status = upb_Decode(buf, size, dst, mt, extreg, 0, arena); + if (d_status != kUpb_DecodeStatus_Ok) { + upb_Arena_Free(encode_arena); + return false; + } + upb_Arena_Free(encode_arena); + return true; +} + + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)( + const struct upb_Message* msg, const upb_MiniTableExtension* e) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return NULL; + + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + if (ext->ext == e) { + return ext; + } + } + } + + return NULL; +} + +upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Extension* ext = (upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e); + if (ext) return ext; + + if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, a)) return NULL; + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + ext = upb_Arena_Malloc(a, sizeof(upb_Extension)); + if (!ext) return NULL; + memset(ext, 0, sizeof(upb_Extension)); + ext->ext = e; + in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeExtension(ext); + return ext; +} + + +#include <math.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +// The latest win32 SDKs have an invalid definition of NAN. +// https://developercommunity.visualstudio.com/t/NAN-is-no-longer-compile-time-constant-i/10688907 +// +// Unfortunately, the `0.0 / 0.0` workaround doesn't work in Clang under C23, so +// try __builtin_nan first, if that exists. +#ifdef _WIN32 +#ifdef __has_builtin +#if __has_builtin(__builtin_nan) +#define UPB_NAN __builtin_nan("0") +#endif +#if __has_builtin(__builtin_inf) +#define UPB_INFINITY __builtin_inf() +#endif +#endif +#ifndef UPB_NAN +#define UPB_NAN 0.0 / 0.0 +#endif +#ifndef UPB_INFINITY +#define UPB_INFINITY 1.0 / 0.0 +#endif +#else +// For !_WIN32, assume math.h works. +#define UPB_NAN NAN +#define UPB_INFINITY INFINITY +#endif + +const float kUpb_FltInfinity = UPB_INFINITY; +const double kUpb_Infinity = UPB_INFINITY; +const double kUpb_NaN = UPB_NAN; + +static size_t _upb_Message_SizeOfInternal(uint32_t count) { + return UPB_SIZEOF_FLEX(upb_Message_Internal, aux_data, count); +} + +bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg, + upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) { + // No internal data, allocate from scratch. + uint32_t capacity = 4; + in = upb_Arena_Malloc(a, _upb_Message_SizeOfInternal(capacity)); + if (!in) return false; + in->size = 0; + in->capacity = capacity; + UPB_PRIVATE(_upb_Message_SetInternal)(msg, in); + } else if (in->capacity == in->size) { + if (in->size == UINT32_MAX) return false; + // Internal data is too small, reallocate. + size_t needed_pow2 = upb_RoundUpToPowerOfTwo(in->size + 1); + if (needed_pow2 > UINT32_MAX) return false; + uint32_t new_capacity = needed_pow2; + if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_Message_Internal, aux_data, + new_capacity)) { + return false; + } + in = upb_Arena_Realloc(a, in, _upb_Message_SizeOfInternal(in->capacity), + _upb_Message_SizeOfInternal(new_capacity)); + if (!in) return false; + in->capacity = new_capacity; + UPB_PRIVATE(_upb_Message_SetInternal)(msg, in); + } + UPB_ASSERT(in->capacity - in->size >= 1); + return true; +} + +#ifdef UPB_TRACING_ENABLED +static void (*_message_trace_handler)(const upb_MiniTable*, const upb_Arena*); + +void upb_Message_LogNewMessage(const upb_MiniTable* m, const upb_Arena* arena) { + if (_message_trace_handler) { + _message_trace_handler(m, arena); + } +} + +void upb_Message_SetNewMessageTraceHandler(void (*handler)(const upb_MiniTable*, + const upb_Arena*)) { + _message_trace_handler = handler; +} +#endif // UPB_TRACING_ENABLED + + +#include <stddef.h> + + +// Must be last. + +bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField** out_f, + upb_MessageValue* out_v, + size_t* iter) { + const size_t count = upb_MiniTable_FieldCount(m); + size_t i = *iter; + + while (++i < count) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + const void* src = UPB_PRIVATE(_upb_Message_DataPtr)(msg, f); + + upb_MessageValue val; + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, &val, src); + + // Skip field if unset or empty. + if (upb_MiniTableField_HasPresence(f)) { + if (!upb_Message_HasBaseField(msg, f)) continue; + } else { + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(f, src)) continue; + + if (upb_MiniTableField_IsArray(f)) { + if (upb_Array_Size(val.array_val) == 0) continue; + } else if (upb_MiniTableField_IsMap(f)) { + if (upb_Map_Size(val.map_val) == 0) continue; + } + } + + *out_f = f; + *out_v = val; + *iter = i; + return true; + } + + return false; +} + + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +typedef struct { + upb_MdDecoder base; + upb_Arena* arena; + upb_MiniTableEnum* enum_table; + uint32_t enum_value_count; + uint32_t enum_data_count; + uint32_t enum_data_capacity; +} upb_MdEnumDecoder; + +static size_t upb_MiniTableEnum_Size(uint32_t count) { + return UPB_SIZEOF_FLEX(upb_MiniTableEnum, UPB_PRIVATE(data), count); +} + +static upb_MiniTableEnum* _upb_MiniTable_AddEnumDataMember(upb_MdEnumDecoder* d, + uint32_t val) { + if (d->enum_data_count == d->enum_data_capacity) { + size_t old_sz = upb_MiniTableEnum_Size(d->enum_data_capacity); + if (d->enum_data_capacity > UINT32_MAX / 2) { + upb_MdDecoder_ErrorJmp(&d->base, "Out of memory"); + } + uint32_t new_capacity = UPB_MAX(2, d->enum_data_capacity * 2); + if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_MiniTableEnum, UPB_PRIVATE(data), + new_capacity)) { + upb_MdDecoder_ErrorJmp(&d->base, "Out of memory"); + } + size_t new_sz = upb_MiniTableEnum_Size(new_capacity); + d->enum_table = upb_Arena_Realloc(d->arena, d->enum_table, old_sz, new_sz); + upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); + d->enum_data_capacity = new_capacity; + } + d->enum_table->UPB_PRIVATE(data)[d->enum_data_count++] = val; + return d->enum_table; +} + +static void upb_MiniTableEnum_BuildValue(upb_MdEnumDecoder* d, uint32_t val) { + upb_MiniTableEnum* table = d->enum_table; + d->enum_value_count++; + if (table->UPB_PRIVATE(value_count) || + (val > 512 && d->enum_value_count < val / 32)) { + if (table->UPB_PRIVATE(value_count) == 0) { + UPB_ASSERT(d->enum_data_count == table->UPB_PRIVATE(mask_limit) / 32); + } + table = _upb_MiniTable_AddEnumDataMember(d, val); + table->UPB_PRIVATE(value_count)++; + } else { + uint32_t new_mask_limit = ((val / 32) + 1) * 32; + while (table->UPB_PRIVATE(mask_limit) < new_mask_limit) { + table = _upb_MiniTable_AddEnumDataMember(d, 0); + table->UPB_PRIVATE(mask_limit) += 32; + } + table->UPB_PRIVATE(data)[val / 32] |= 1ULL << (val % 32); + } +} + +static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( + upb_MdEnumDecoder* d, const char* data, size_t len) { + // If the string is non-empty then it must begin with a version tag. + if (len) { + if (*data != kUpb_EncodedVersion_EnumV1) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid enum version: %c", *data); + } + data++; + len--; + } + + upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); + + // Guarantee at least 64 bits of mask without checking mask size. + d->enum_table->UPB_PRIVATE(mask_limit) = 64; + d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); + d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); + + d->enum_table->UPB_PRIVATE(value_count) = 0; + + const char* ptr = data; + uint32_t base = 0; + + while (ptr < d->base.end) { + char ch = *ptr++; + if (ch <= kUpb_EncodedValue_MaxEnumMask) { + uint32_t mask = _upb_FromBase92(ch); + for (int i = 0; i < 5; i++, base++, mask >>= 1) { + if (mask & 1) upb_MiniTableEnum_BuildValue(d, base); + } + } else if (kUpb_EncodedValue_MinSkip <= ch && + ch <= kUpb_EncodedValue_MaxSkip) { + uint32_t skip; + ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, ch, + kUpb_EncodedValue_MinSkip, + kUpb_EncodedValue_MaxSkip, &skip); + base += skip; + } else { + upb_MdDecoder_ErrorJmp(&d->base, "Unexpected character: %c", ch); + } + } + + return d->enum_table; +} + +static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum( + upb_MdEnumDecoder* const decoder, const char* const data, + size_t const len) { + if (UPB_SETJMP(decoder->base.err) != 0) return NULL; + return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len); +} + +upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len, + upb_Arena* arena, + upb_Status* status) { + uint32_t initial_capacity = 2; + upb_MdEnumDecoder decoder = { + .base = + { + .end = UPB_PTRADD(data, len), + .status = status, + }, + .arena = arena, + .enum_table = + upb_Arena_Malloc(arena, upb_MiniTableEnum_Size(initial_capacity)), + .enum_value_count = 0, + .enum_data_count = 0, + .enum_data_capacity = initial_capacity, + }; + + return upb_MtDecoder_BuildMiniTableEnum(&decoder, data, len); +} + + +#include <inttypes.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Our awkward dance for including fasttable only when it is enabled. +#if UPB_FASTTABLE +#define UPB_INCLUDE_FAST_DECODE +#endif + +#ifdef UPB_INCLUDE_FAST_DECODE +#endif + +#undef UPB_INCLUDE_FAST_DECODE + +// Must be last. + +// We reserve unused hasbits to make room for upb_Message fields. +#define kUpb_Reserved_Hasbytes sizeof(struct upb_Message) + +// 64 is the first hasbit that we currently use. +#define kUpb_Reserved_Hasbits (kUpb_Reserved_Hasbytes * 8) + +#define kUpb_OneOfLayoutItem_IndexSentinel ((uint16_t)-1) + +// Stores the field number of the present value of the oneof +#define kUpb_OneOf_CaseFieldRep (kUpb_FieldRep_4Byte) + +// The maximum field number that can be encoded on the wire. +// Note that this limit does not apply to MessageSet, which can have field +// numbers up to INT32_MAX. +#define kUpb_MaxFieldNumber ((1 << 29) - 1) + +typedef struct { + // Index of the corresponding field. The field's offset will be the index of + // the next field in a linked list. + uint16_t field_index; + // This enum is stored in bytes to avoid trailing padding while preserving + // two-byte alignment. + uint8_t /* upb_FieldRep*/ rep; +} upb_OneOfLayoutItem; + +typedef struct { + upb_OneOfLayoutItem* data; + size_t size; + size_t buf_capacity_bytes; +} upb_OneOfLayoutItemVector; + +typedef struct { + upb_MdDecoder base; + upb_MiniTableField* fields; + upb_MiniTablePlatform platform; + upb_OneOfLayoutItemVector oneofs; + upb_Arena* arena; + // Initially tracks the count of each field rep type; then, during assignment, + // tracks the base offset for the next processed field of the given rep. + uint16_t rep_counts_offsets[kUpb_FieldRep_Max + 1]; + uint32_t sub_count; + bool is_extension; + + // When building fasttables, we don't know the total size of the table until + // we're done decoding, so we allocate a temporary table on the stack and + // allocate the real thing from the arena later. + upb_MiniTable table; +} upb_MtDecoder; + +// In each field's offset, we temporarily store a presence classifier: +enum PresenceClass { + kNoPresence = 0, + kHasbitPresence = 1, + kRequiredPresence = 2, + kOneofBase = 3, + // Negative values refer to a specific oneof with that number. Positive + // values >= kOneofBase indicate that this field is in a oneof, and specify + // the next field in this oneof's linked list. +}; + +static bool upb_MtDecoder_FieldIsPackable(upb_MiniTableField* field) { + return (field->UPB_PRIVATE(mode) & kUpb_FieldMode_Array) && + upb_FieldType_IsPackable(field->UPB_PRIVATE(descriptortype)); +} + +typedef struct { + uint16_t submsg_count; + uint16_t subenum_count; +} upb_SubCounts; + +static void upb_MiniTable_SetTypeAndSub(upb_MtDecoder* d, + upb_MiniTableField* field, + upb_FieldType type, + uint64_t msg_modifiers, + bool is_proto3_enum) { + if (is_proto3_enum) { + UPB_ASSERT(type == kUpb_FieldType_Enum); + type = kUpb_FieldType_Int32; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; + } else if (type == kUpb_FieldType_String && + !(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) { + type = kUpb_FieldType_Bytes; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; + } + + field->UPB_PRIVATE(descriptortype) = type; + + if (upb_MtDecoder_FieldIsPackable(field) && + (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) { + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsPacked; + } + + // We initially set `submsg_ofs` to the index of the sub in the list of subs. + // Later, we'll update it to be a relative byte offset. + if (type == kUpb_FieldType_Message || type == kUpb_FieldType_Group || + type == kUpb_FieldType_Enum) { + field->UPB_PRIVATE(submsg_ofs) = d->sub_count++; + } else { + field->UPB_PRIVATE(submsg_ofs) = kUpb_NoSub; + } +} + +static const char kUpb_EncodedToType[] = { + [kUpb_EncodedType_Double] = kUpb_FieldType_Double, + [kUpb_EncodedType_Float] = kUpb_FieldType_Float, + [kUpb_EncodedType_Int64] = kUpb_FieldType_Int64, + [kUpb_EncodedType_UInt64] = kUpb_FieldType_UInt64, + [kUpb_EncodedType_Int32] = kUpb_FieldType_Int32, + [kUpb_EncodedType_Fixed64] = kUpb_FieldType_Fixed64, + [kUpb_EncodedType_Fixed32] = kUpb_FieldType_Fixed32, + [kUpb_EncodedType_Bool] = kUpb_FieldType_Bool, + [kUpb_EncodedType_String] = kUpb_FieldType_String, + [kUpb_EncodedType_Group] = kUpb_FieldType_Group, + [kUpb_EncodedType_Message] = kUpb_FieldType_Message, + [kUpb_EncodedType_Bytes] = kUpb_FieldType_Bytes, + [kUpb_EncodedType_UInt32] = kUpb_FieldType_UInt32, + [kUpb_EncodedType_OpenEnum] = kUpb_FieldType_Enum, + [kUpb_EncodedType_SFixed32] = kUpb_FieldType_SFixed32, + [kUpb_EncodedType_SFixed64] = kUpb_FieldType_SFixed64, + [kUpb_EncodedType_SInt32] = kUpb_FieldType_SInt32, + [kUpb_EncodedType_SInt64] = kUpb_FieldType_SInt64, + [kUpb_EncodedType_ClosedEnum] = kUpb_FieldType_Enum, +}; + +static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch, + upb_MiniTableField* field, + uint64_t msg_modifiers) { + static const char kUpb_EncodedToFieldRep[] = { + [kUpb_EncodedType_Double] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_Float] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_Int64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_UInt64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_Int32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_Fixed64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_Fixed32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_Bool] = kUpb_FieldRep_1Byte, + [kUpb_EncodedType_String] = kUpb_FieldRep_StringView, + [kUpb_EncodedType_Bytes] = kUpb_FieldRep_StringView, + [kUpb_EncodedType_UInt32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_OpenEnum] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_SFixed32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_SFixed64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_SInt32] = kUpb_FieldRep_4Byte, + [kUpb_EncodedType_SInt64] = kUpb_FieldRep_8Byte, + [kUpb_EncodedType_ClosedEnum] = kUpb_FieldRep_4Byte, + }; + + char pointer_rep = d->platform == kUpb_MiniTablePlatform_32Bit + ? kUpb_FieldRep_4Byte + : kUpb_FieldRep_8Byte; + + int8_t type = _upb_FromBase92(ch); + if (ch >= _upb_ToBase92(kUpb_EncodedType_RepeatedBase)) { + type -= kUpb_EncodedType_RepeatedBase; + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Array; + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(offset) = kNoPresence; + } else { + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Scalar; + field->UPB_PRIVATE(offset) = kHasbitPresence; + if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) { + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; + } else if ((unsigned long)type >= sizeof(kUpb_EncodedToFieldRep)) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid field type: %d", (int)type); + } else { + field->UPB_PRIVATE(mode) |= kUpb_EncodedToFieldRep[type] + << kUpb_FieldRep_Shift; + } + } + if ((unsigned long)type >= sizeof(kUpb_EncodedToType)) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid field type: %d", (int)type); + } + upb_MiniTable_SetTypeAndSub(d, field, kUpb_EncodedToType[type], msg_modifiers, + type == kUpb_EncodedType_OpenEnum); +} + +static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, + uint32_t message_modifiers, + uint32_t field_modifiers, + upb_MiniTableField* field) { + if (field_modifiers & kUpb_EncodedFieldModifier_FlipPacked) { + if (!upb_MtDecoder_FieldIsPackable(field)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Cannot flip packed on unpackable field %" PRIu32, + upb_MiniTableField_Number(field)); + } + field->UPB_PRIVATE(mode) ^= kUpb_LabelFlags_IsPacked; + } + + if (field_modifiers & kUpb_EncodedFieldModifier_FlipValidateUtf8) { + if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Bytes || + !(field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsAlternate)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Cannot flip ValidateUtf8 on field %" PRIu32 + ", type=%d, mode=%d", + upb_MiniTableField_Number(field), + (int)field->UPB_PRIVATE(descriptortype), + (int)field->UPB_PRIVATE(mode)); + } + field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_String; + field->UPB_PRIVATE(mode) &= ~kUpb_LabelFlags_IsAlternate; + } + + bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular; + bool required = field_modifiers & kUpb_EncodedFieldModifier_IsRequired; + + // Validate. + if ((singular || required) && field->UPB_PRIVATE(offset) != kHasbitPresence) { + upb_MdDecoder_ErrorJmp(&d->base, + "Invalid modifier(s) for repeated field %" PRIu32, + upb_MiniTableField_Number(field)); + } + if (singular && required) { + upb_MdDecoder_ErrorJmp( + &d->base, "Field %" PRIu32 " cannot be both singular and required", + upb_MiniTableField_Number(field)); + } + + if (singular && upb_MiniTableField_IsSubMessage(field)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Field %" PRIu32 " cannot be a singular submessage", + upb_MiniTableField_Number(field)); + } + + if (singular) field->UPB_PRIVATE(offset) = kNoPresence; + if (required) { + field->UPB_PRIVATE(offset) = kRequiredPresence; + } +} + +static void upb_MtDecoder_PushOneof(upb_MtDecoder* d, + upb_OneOfLayoutItem item) { + if (item.field_index == kUpb_OneOfLayoutItem_IndexSentinel) { + upb_MdDecoder_ErrorJmp(&d->base, "Empty oneof"); + } + if ((d->oneofs.size + 1) * sizeof(*d->oneofs.data) > + d->oneofs.buf_capacity_bytes) { + size_t new_cap = UPB_MAX(8, d->oneofs.size * 2) * sizeof(*d->oneofs.data); + d->oneofs.data = + upb_grealloc(d->oneofs.data, d->oneofs.buf_capacity_bytes, new_cap); + upb_MdDecoder_CheckOutOfMemory(&d->base, d->oneofs.data); + d->oneofs.buf_capacity_bytes = new_cap; + } + item.field_index -= kOneofBase; + + d->rep_counts_offsets[kUpb_OneOf_CaseFieldRep]++; + d->rep_counts_offsets[item.rep]++; + d->oneofs.data[d->oneofs.size++] = item; +} + +static size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep, + upb_MiniTablePlatform platform) { + enum { string_view_size_32 = 8, string_view_size_64 = 16 }; + UPB_STATIC_ASSERT(sizeof(upb_StringView) == + UPB_SIZE(string_view_size_32, string_view_size_64), + "StringView size mismatch"); + static const uint8_t kRepToSize32[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_size_32, + [kUpb_FieldRep_8Byte] = 8, + }; + static const uint8_t kRepToSize64[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_size_64, + [kUpb_FieldRep_8Byte] = 8, + }; + return platform == kUpb_MiniTablePlatform_32Bit ? kRepToSize32[rep] + : kRepToSize64[rep]; +} + +static size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep, + upb_MiniTablePlatform platform) { + enum { string_view_align_32 = 4, string_view_align_64 = 8 }; + UPB_STATIC_ASSERT(UPB_ALIGN_OF(upb_StringView) == + UPB_SIZE(string_view_align_32, string_view_align_64), + "StringView size mismatch"); + + static const uint8_t kRepToAlign32[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_align_32, + [kUpb_FieldRep_8Byte] = 8, + }; + static const uint8_t kRepToAlign64[] = { + [kUpb_FieldRep_1Byte] = 1, + [kUpb_FieldRep_4Byte] = 4, + [kUpb_FieldRep_StringView] = string_view_align_64, + [kUpb_FieldRep_8Byte] = 8, + }; + return platform == kUpb_MiniTablePlatform_32Bit ? kRepToAlign32[rep] + : kRepToAlign64[rep]; +} + +static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d, + const char* ptr, + char first_ch, + upb_OneOfLayoutItem* item) { + uint32_t field_num; + ptr = upb_MdDecoder_DecodeBase92Varint( + &d->base, ptr, first_ch, kUpb_EncodedValue_MinOneofField, + kUpb_EncodedValue_MaxOneofField, &field_num); + upb_MiniTableField* f = + (void*)upb_MiniTable_FindFieldByNumber(&d->table, field_num); + + if (!f) { + upb_MdDecoder_ErrorJmp(&d->base, + "Couldn't add field number %" PRIu32 + " to oneof, no such field number.", + field_num); + } + if (f->UPB_PRIVATE(offset) != kHasbitPresence) { + upb_MdDecoder_ErrorJmp( + &d->base, + "Cannot add repeated, required, or singular field %" PRIu32 + " to oneof.", + field_num); + } + + // Oneof storage must be large enough to accommodate the largest member. + int rep = f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift; + size_t new_size = upb_MtDecoder_SizeOfRep(rep, d->platform); + size_t new_align = upb_MtDecoder_AlignOfRep(rep, d->platform); + size_t current_size = upb_MtDecoder_SizeOfRep(item->rep, d->platform); + size_t current_align = upb_MtDecoder_AlignOfRep(item->rep, d->platform); + + if (new_size > current_size || + (new_size == current_size && new_align > current_align)) { + UPB_ASSERT(new_align >= current_align); + item->rep = rep; + } else { + UPB_ASSERT(current_align >= new_align); + } + // Prepend this field to the linked list. + f->UPB_PRIVATE(offset) = item->field_index; + item->field_index = (f - d->fields) + kOneofBase; + return ptr; +} + +static const char* upb_MtDecoder_DecodeOneofs(upb_MtDecoder* d, + const char* ptr) { + upb_OneOfLayoutItem item = { + .rep = 0, .field_index = kUpb_OneOfLayoutItem_IndexSentinel}; + while (ptr < d->base.end) { + char ch = *ptr++; + if (ch == kUpb_EncodedValue_FieldSeparator) { + // Field separator, no action needed. + } else if (ch == kUpb_EncodedValue_OneofSeparator) { + // End of oneof. + upb_MtDecoder_PushOneof(d, item); + item.field_index = + kUpb_OneOfLayoutItem_IndexSentinel; // Move to next oneof. + } else { + ptr = upb_MtDecoder_DecodeOneofField(d, ptr, ch, &item); + } + } + + // Push final oneof. + upb_MtDecoder_PushOneof(d, item); + return ptr; +} + +static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d, + const char* ptr, char first_ch, + upb_MiniTableField* last_field, + uint64_t* msg_modifiers) { + uint32_t mod; + ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, first_ch, + kUpb_EncodedValue_MinModifier, + kUpb_EncodedValue_MaxModifier, &mod); + if (last_field) { + upb_MtDecoder_ModifyField(d, *msg_modifiers, mod, last_field); + } else { + if (d->is_extension) { + upb_MdDecoder_ErrorJmp(&d->base, + "Extensions cannot have message modifiers"); + } + *msg_modifiers = mod; + } + + return ptr; +} + +size_t upb_MtDecoder_PtrSize(upb_MtDecoder* d) { + return d->platform == kUpb_MiniTablePlatform_32Bit ? 4 : 8; +} + +static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, + upb_MiniTableSubInternal* subs) { + // The `ofs` variable tracks byte offset between the current field and the + // current entry in the `subs` array. Whenever we move to the next entry in + // the `fields` array, the offset decreases by the size of the field, but + // whenever we move to the next entry in the `subs` array, the offset + // *increases* by the size of the entry in the `subs` array. + UPB_ASSERT((char*)subs >= (char*)d->fields); + size_t ofs = (char*)subs - (char*)d->fields; + uintptr_t ptr_size = upb_MtDecoder_PtrSize(d); + for (int i = 0; i < d->table.UPB_PRIVATE(field_count); + i++, ofs -= sizeof(upb_MiniTableField)) { + upb_MiniTableField* f = &d->fields[i]; + if (f->UPB_PRIVATE(submsg_ofs) == kUpb_NoSub) continue; + size_t u32_ofs = ofs / kUpb_SubmsgOffsetBytes; + UPB_ASSERT((ofs % 4) == 0); + UPB_ASSERT((i * sizeof(upb_MiniTableField) + ofs) % ptr_size == 0); + if (u32_ofs > UINT16_MAX) { + upb_MdDecoder_ErrorJmp(&d->base, "Submessage offset overflow"); + } + f->UPB_PRIVATE(submsg_ofs) = u32_ofs; + ofs += ptr_size; + } +} + +static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, + size_t len, void* fields, + size_t field_size, + uint16_t* field_count) { + uint64_t msg_modifiers = 0; + uint32_t last_field_number = 0; + upb_MiniTableField* last_field = NULL; + bool need_dense_below = !d->is_extension; + + d->base.end = UPB_PTRADD(ptr, len); + + while (ptr < d->base.end) { + char ch = *ptr++; + if (ch <= kUpb_EncodedValue_MaxField) { + if (d->is_extension && last_field) { + // For extensions, consume only a single field and then return. + return --ptr; + } + upb_MiniTableField* field = fields; + *field_count += 1; + fields = (char*)fields + field_size; + uint32_t number = ++last_field_number; + if (number == 0 || (number > kUpb_MaxFieldNumber && !d->is_extension)) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid field number: %" PRIu32, + number); + } + field->UPB_PRIVATE(number) = number; + last_field = field; + upb_MiniTable_SetField(d, ch, field, msg_modifiers); + } else if (kUpb_EncodedValue_MinModifier <= ch && + ch <= kUpb_EncodedValue_MaxModifier) { + ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers); + if (msg_modifiers & kUpb_MessageModifier_IsExtendable) { + d->table.UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable; + } + } else if (ch == kUpb_EncodedValue_End) { + if (d->is_extension) { + upb_MdDecoder_ErrorJmp(&d->base, "Extensions cannot have oneofs."); + } + ptr = upb_MtDecoder_DecodeOneofs(d, ptr); + } else if (kUpb_EncodedValue_MinSkip <= ch && + ch <= kUpb_EncodedValue_MaxSkip) { + if (need_dense_below) { + d->table.UPB_PRIVATE(dense_below) = d->table.UPB_PRIVATE(field_count); + need_dense_below = false; + } + uint32_t skip; + ptr = upb_MdDecoder_DecodeBase92Varint(&d->base, ptr, ch, + kUpb_EncodedValue_MinSkip, + kUpb_EncodedValue_MaxSkip, &skip); + last_field_number += skip; + last_field_number--; // Next field seen will increment. + } else { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid char: %c", ch); + } + } + + if (need_dense_below) { + d->table.UPB_PRIVATE(dense_below) = d->table.UPB_PRIVATE(field_count); + } + + return ptr; +} + +static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, + size_t len) { + const size_t bytes_per_field = + sizeof(upb_MiniTableField) + sizeof(upb_MiniTableSubInternal); + // Buffer length is an upper bound on the number of fields. We will return + // what we don't use. + if ((SIZE_MAX - 4) / bytes_per_field < len) { + upb_MdDecoder_ErrorJmp(&d->base, "MiniDescriptor is too large"); + } + // Max size used per field is a upb_MiniTableField and a + // upb_MiniTableSubInternal. There could also be up to 4 bytes of padding, + // since sizeof(upb_MiniTableField) == 12 and + // alignof(upb_MiniTableSubInternal) == 8. + UPB_STATIC_ASSERT(UPB_ALIGN_OF(upb_MiniTableSubInternal) - + UPB_ALIGN_OF(upb_MiniTableField) <= + 4, + "alignment difference is too large"); + const size_t initial_bytes = bytes_per_field * len + 4; + d->fields = upb_Arena_Malloc(d->arena, initial_bytes); + upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); + + d->table.UPB_PRIVATE(field_count) = 0; + d->table.UPB_PRIVATE(fields) = d->fields; + upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields), + &d->table.UPB_PRIVATE(field_count)); + size_t field_bytes = + UPB_ALIGN_UP(d->table.UPB_PRIVATE(field_count) * sizeof(*d->fields), + upb_MtDecoder_PtrSize(d)); + upb_MiniTableSubInternal* subs = + UPB_PTR_AT(d->fields, field_bytes, upb_MiniTableSubInternal); + memset(subs, 0, sizeof(upb_MiniTableSubInternal) * d->sub_count); + + // We now know how much space we actually used, so shrink the allocation to + // that size. + size_t final_bytes = + field_bytes + sizeof(upb_MiniTableSubInternal) * d->sub_count; + upb_Arena_ShrinkLast(d->arena, d->fields, initial_bytes, final_bytes); + upb_MtDecoder_AllocateSubs(d, subs); +} + +static void upb_MtDecoder_CalculateAlignments(upb_MtDecoder* d) { + // Add alignment counts for non-oneof fields (oneofs were added already) + int n = d->table.UPB_PRIVATE(field_count); + for (int i = 0; i < n; i++) { + upb_MiniTableField* f = &d->fields[i]; + if (f->UPB_PRIVATE(offset) >= kOneofBase) continue; + d->rep_counts_offsets[f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift]++; + } + + // Reserve properly aligned space for each type of field representation + // present in this message. When we iterate over the fields, they will obtain + // their offset from within the region matching their alignment requirements. + size_t base = d->table.UPB_PRIVATE(size); + // Start with the lowest alignment requirement, going up, because: + // 1. If there are presence bits, we won't be aligned to start, but adding + // some lower-alignment fields may get us closer without wasting space to + // padding. + // 2. The allocator enforces 8 byte alignment, so moving intermediate padding + // to trailing padding doesn't save us anything. + for (upb_FieldRep rep = kUpb_FieldRep_1Byte; rep <= kUpb_FieldRep_Max; + rep++) { + uint16_t count = d->rep_counts_offsets[rep]; + if (count) { + base = UPB_ALIGN_UP(base, upb_MtDecoder_AlignOfRep(rep, d->platform)); + // This entry now tracks the base offset for this field representation + // type, instead of the count + d->rep_counts_offsets[rep] = base; + base += upb_MtDecoder_SizeOfRep(rep, d->platform) * count; + } + } + static const size_t max = UINT16_MAX; + if (base > max) { + upb_MdDecoder_ErrorJmp( + &d->base, "Message size exceeded maximum size of %zu bytes", max); + } + d->table.UPB_PRIVATE(size) = (uint16_t)base; +} + +static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) { + return (n + d - 1) / d; +} + +static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { + int n = d->table.UPB_PRIVATE(field_count); + size_t last_hasbit = kUpb_Reserved_Hasbits - 1; + + // First assign required fields, which must have the lowest hasbits. + for (int i = 0; i < n; i++) { + upb_MiniTableField* field = + (upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i]; + if (field->UPB_PRIVATE(offset) == kRequiredPresence) { + field->presence = ++last_hasbit; + } else if (field->UPB_PRIVATE(offset) == kNoPresence) { + field->presence = 0; + } + } + if (last_hasbit >= kUpb_Reserved_Hasbits + 63) { + upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields"); + } + + d->table.UPB_PRIVATE(required_count) = + last_hasbit - (kUpb_Reserved_Hasbits - 1); + UPB_ASSERT(d->table.UPB_PRIVATE(required_count) < 64); + + // Next assign non-required hasbit fields. + for (int i = 0; i < n; i++) { + upb_MiniTableField* field = + (upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i]; + if (field->UPB_PRIVATE(offset) == kHasbitPresence) { + field->presence = ++last_hasbit; + } + } + + d->table.UPB_PRIVATE(size) = + last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0; +} + +static size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) { + size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform); + size_t offset = d->rep_counts_offsets[rep]; + d->rep_counts_offsets[rep] += size; + return offset; +} + +static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { + upb_MiniTableField* field_end = + UPB_PTRADD(d->fields, d->table.UPB_PRIVATE(field_count)); + for (upb_MiniTableField* field = d->fields; field < field_end; field++) { + if (field->UPB_PRIVATE(offset) >= kOneofBase) continue; + field->UPB_PRIVATE(offset) = + upb_MtDecoder_Place(d, field->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift); + } + + upb_OneOfLayoutItem* oneof_end = UPB_PTRADD(d->oneofs.data, d->oneofs.size); + + for (upb_OneOfLayoutItem* item = d->oneofs.data; item < oneof_end; item++) { + upb_MiniTableField* f = &d->fields[item->field_index]; + uint16_t case_offset = upb_MtDecoder_Place(d, kUpb_OneOf_CaseFieldRep); + uint16_t data_offset = upb_MtDecoder_Place(d, item->rep); + while (true) { + f->presence = ~case_offset; + uint16_t next_offset = f->UPB_PRIVATE(offset); + f->UPB_PRIVATE(offset) = data_offset; + if (next_offset == kUpb_OneOfLayoutItem_IndexSentinel) break; + UPB_ASSERT(next_offset - kOneofBase < d->table.UPB_PRIVATE(field_count)); + f = &d->fields[next_offset - kOneofBase]; + } + } + + // Since messages are always allocated on arenas, we can save repeatedly + // realigning by doing alignment at minitable construction time. We don't want + // to align to UPB_MALLOC_ALIGN because it can change with sanitizers, and if + // we're generating code we don't want to calculate size differently depending + // on the proto compiler's host or build configuration. + d->table.UPB_PRIVATE(size) = + UPB_ALIGN_UP(d->table.UPB_PRIVATE(size), kUpb_Message_Align); +} + +static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d, + const upb_MiniTableField* f, + uint32_t expected_num) { + const char* name = expected_num == 1 ? "key" : "val"; + const uint32_t f_number = upb_MiniTableField_Number(f); + if (f_number != expected_num) { + upb_MdDecoder_ErrorJmp(&d->base, + "map %s did not have expected number (%d vs %d)", + name, expected_num, f_number); + } + + if (!upb_MiniTableField_IsScalar(f)) { + upb_MdDecoder_ErrorJmp( + &d->base, "map %s cannot be repeated or map, or be in oneof", name); + } + + uint32_t not_ok_types; + if (expected_num == 1) { + not_ok_types = (1 << kUpb_FieldType_Float) | (1 << kUpb_FieldType_Double) | + (1 << kUpb_FieldType_Message) | (1 << kUpb_FieldType_Group) | + (1 << kUpb_FieldType_Bytes) | (1 << kUpb_FieldType_Enum); + } else { + not_ok_types = 1 << kUpb_FieldType_Group; + } + + if ((1 << upb_MiniTableField_Type(f)) & not_ok_types) { + upb_MdDecoder_ErrorJmp(&d->base, "map %s cannot have type %d", name, + (int)f->UPB_PRIVATE(descriptortype)); + } +} + +static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, + size_t len) { + upb_MtDecoder_ParseMessage(d, data, len); + upb_MtDecoder_AssignHasbits(d); + + if (UPB_UNLIKELY(d->table.UPB_PRIVATE(field_count) != 2)) { + upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map", + d->table.UPB_PRIVATE(field_count)); + UPB_UNREACHABLE(); + } + + if (d->oneofs.size != 0) { + upb_MdDecoder_ErrorJmp(&d->base, "Map entry cannot have oneof"); + } + + upb_MtDecoder_ValidateEntryField(d, &d->table.UPB_PRIVATE(fields)[0], 1); + upb_MtDecoder_ValidateEntryField(d, &d->table.UPB_PRIVATE(fields)[1], 2); + + d->fields[0].UPB_PRIVATE(offset) = offsetof(upb_MapEntry, k); + d->fields[1].UPB_PRIVATE(offset) = offsetof(upb_MapEntry, v); + d->table.UPB_PRIVATE(size) = sizeof(upb_MapEntry); + + // Map entries have a special bit set to signal it's a map entry, used in + // upb_MiniTable_SetSubMessage() below. + d->table.UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry; +} + +static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, + size_t len) { + if (len > 0) { + upb_MdDecoder_ErrorJmp(&d->base, "Invalid message set encode length: %zu", + len); + } + + upb_MiniTable* ret = &d->table; + ret->UPB_PRIVATE(size) = kUpb_Reserved_Hasbytes; + ret->UPB_PRIVATE(field_count) = 0; + ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet; + ret->UPB_PRIVATE(dense_below) = 0; + ret->UPB_PRIVATE(table_mask) = -1; + ret->UPB_PRIVATE(required_count) = 0; +} + +static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( + upb_MtDecoder* decoder, const char* data, size_t len, void** buf, + size_t* buf_size) { + decoder->table.UPB_PRIVATE(size) = kUpb_Reserved_Hasbytes; + decoder->table.UPB_PRIVATE(field_count) = 0; + decoder->table.UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable; + decoder->table.UPB_PRIVATE(dense_below) = 0; + decoder->table.UPB_PRIVATE(table_mask) = -1; + decoder->table.UPB_PRIVATE(required_count) = 0; +#ifdef UPB_TRACING_ENABLED + // MiniTables built from MiniDescriptors will not be able to vend the message + // name unless it is explicitly set with upb_MiniTable_SetFullName(). + decoder->table.UPB_PRIVATE(full_name) = 0; +#endif + + // Strip off and verify the version tag. + if (!len--) goto done; + const char vers = *data++; + + switch (vers) { + case kUpb_EncodedVersion_MapV1: + upb_MtDecoder_ParseMap(decoder, data, len); + break; + + case kUpb_EncodedVersion_MessageV1: + upb_MtDecoder_ParseMessage(decoder, data, len); + upb_MtDecoder_AssignHasbits(decoder); + upb_MtDecoder_CalculateAlignments(decoder); + upb_MtDecoder_AssignOffsets(decoder); + break; + + case kUpb_EncodedVersion_MessageSetV1: + upb_MtDecoder_ParseMessageSet(decoder, data, len); + break; + + default: + upb_MdDecoder_ErrorJmp(&decoder->base, "Invalid message version: %c", + vers); + } + +done: + *buf = decoder->oneofs.data; + *buf_size = decoder->oneofs.buf_capacity_bytes; + size_t mt_size = sizeof(upb_MiniTable); + +#if UPB_FASTTABLE + upb_DecodeFast_TableEntry fasttable[32]; + int fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable); + mt_size += fasttable_size * sizeof(fasttable[0]); +#endif + + upb_MiniTable* ret = upb_Arena_Malloc(decoder->arena, mt_size); + memcpy(ret, &decoder->table, sizeof(*ret)); + +#if UPB_FASTTABLE + ret->UPB_PRIVATE(table_mask) = upb_DecodeFast_GetTableMask(fasttable_size); + for (int i = 0; i < fasttable_size; i++) { + ret->UPB_PRIVATE(fasttable)[i].field_data = fasttable[i].function_data; + ret->UPB_PRIVATE(fasttable)[i].field_parser = + upb_DecodeFast_GetFunctionPointer(fasttable[i].function_idx); + } +#endif + UPB_PRIVATE(upb_MiniTable_CheckInvariants)(ret); + return ret; +} + +static upb_MiniTable* upb_MtDecoder_BuildMiniTableWithBuf( + upb_MtDecoder* const decoder, const char* const data, const size_t len, + void** const buf, size_t* const buf_size) { + if (UPB_SETJMP(decoder->base.err) != 0) { + *buf = decoder->oneofs.data; + *buf_size = decoder->oneofs.buf_capacity_bytes; + return NULL; + } + + return upb_MtDecoder_DoBuildMiniTableWithBuf(decoder, data, len, buf, + buf_size); +} + +upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, void** buf, + size_t* buf_size, + upb_Status* status) { + upb_MtDecoder decoder = { + .base = {.status = status}, + .platform = platform, + .sub_count = 0, + .is_extension = false, + .oneofs = + { + .data = *buf, + .buf_capacity_bytes = *buf_size, + .size = 0, + }, + .arena = arena, + }; + + return upb_MtDecoder_BuildMiniTableWithBuf(&decoder, data, len, buf, + buf_size); +} + +static const char* upb_MtDecoder_DoBuildMiniTableExtension( + upb_MtDecoder* decoder, const char* data, size_t len, + upb_MiniTableExtension* ext, const upb_MiniTable* extendee, + upb_MiniTableSub sub) { + if (!(extendee->UPB_PRIVATE(ext) & + (kUpb_ExtMode_Extendable | kUpb_ExtMode_IsMessageSet))) { + upb_MdDecoder_ErrorJmp(&decoder->base, "Extendee is not extendable"); + } + + // If the string is non-empty then it must begin with a version tag. + if (len) { + if (*data != kUpb_EncodedVersion_ExtensionV1) { + upb_MdDecoder_ErrorJmp(&decoder->base, "Invalid ext version: %c", *data); + } + data++; + len--; + } + + uint16_t count = 0; + const char* ret = + upb_MtDecoder_Parse(decoder, data, len, ext, sizeof(*ext), &count); + if (!ret || count != 1) return NULL; + + upb_MiniTableField* f = &ext->UPB_PRIVATE(field); + + f->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsExtension; + f->UPB_PRIVATE(offset) = 0; + f->presence = 0; + + // In upb_MiniTableExtension, the `sub` member is a pointer-sized member that + // directly follows the `field` member. + f->UPB_PRIVATE(submsg_ofs) = + UPB_ALIGN_UP(sizeof(upb_MiniTableField), upb_MtDecoder_PtrSize(decoder)) / + kUpb_SubmsgOffsetBytes; + + if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) { + // Extensions of MessageSet must be messages. + if (!upb_MiniTableField_IsSubMessage(f)) return NULL; + + // Extensions of MessageSet must be non-repeating. + if (upb_MiniTableField_IsArray(f)) return NULL; + } + + ext->UPB_PRIVATE(extendee) = extendee; + ext->UPB_PRIVATE(sub) = sub; + + return ret; +} + +static const char* upb_MtDecoder_BuildMiniTableExtension( + upb_MtDecoder* const decoder, const char* const data, const size_t len, + upb_MiniTableExtension* const ext, const upb_MiniTable* const extendee, + const upb_MiniTableSub sub) { + if (UPB_SETJMP(decoder->base.err) != 0) return NULL; + return upb_MtDecoder_DoBuildMiniTableExtension(decoder, data, len, ext, + extendee, sub); +} + +const char* _upb_MiniTableExtension_Init(const char* data, size_t len, + upb_MiniTableExtension* ext, + const upb_MiniTable* extendee, + upb_MiniTableSub sub, + upb_MiniTablePlatform platform, + upb_Status* status) { + upb_MtDecoder decoder = { + .base = {.status = status}, + .arena = NULL, + .platform = platform, + .sub_count = 0, + .is_extension = true, + }; + + return upb_MtDecoder_BuildMiniTableExtension(&decoder, data, len, ext, + extendee, sub); +} + +upb_MiniTableExtension* _upb_MiniTableExtension_Build( + const char* data, size_t len, const upb_MiniTable* extendee, + upb_MiniTableSub sub, upb_MiniTablePlatform platform, upb_Arena* arena, + upb_Status* status) { + upb_MiniTableExtension* ext = + upb_Arena_Malloc(arena, sizeof(upb_MiniTableExtension)); + if (UPB_UNLIKELY(!ext)) return NULL; + + const char* ptr = _upb_MiniTableExtension_Init(data, len, ext, extendee, sub, + platform, status); + if (UPB_UNLIKELY(!ptr)) return NULL; + + return ext; +} + +upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, upb_Status* status) { + void* buf = NULL; + size_t size = 0; + upb_MiniTable* ret = upb_MiniTable_BuildWithBuf(data, len, platform, arena, + &buf, &size, status); + upb_gfree(buf); + return ret; +} + + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, + upb_MiniTableField* field, + const upb_MiniTable* sub) { + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); + UPB_ASSERT(sub); + + const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; + + switch (field->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Message: + if (sub_is_map) { + const bool table_is_map = + table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; + if (UPB_UNLIKELY(table_is_map)) return false; + + field->UPB_PRIVATE(mode) = + (field->UPB_PRIVATE(mode) & ~kUpb_FieldMode_Mask) | + kUpb_FieldMode_Map; + } + break; + + case kUpb_FieldType_Group: + if (UPB_UNLIKELY(sub_is_map)) return false; + break; + + default: + return false; + } + + upb_MiniTableSubInternal* table_sub = + UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + // TODO: Add this assert back once YouTube is updated to not call + // this function repeatedly. + // UPB_ASSERT(upb_MiniTable_GetSubMessageTable(table, field) == NULL); + table_sub->UPB_PRIVATE(submsg) = sub; + return true; +} + +bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, + const upb_MiniTableEnum* sub) { + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); + UPB_ASSERT(sub); + + if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Enum) { + return false; + } + + if ((table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry) && + !upb_MiniTableEnum_CheckValue(sub, 0)) { + // An enum used in a map must include 0 as a value. This matches a check + // performed in protoc ("Enum value in map must define 0 as the first + // value"). Protoc should ensure that we never get here. + // + // This ends up being important if we receive wire messages where a map + // entry omits the value (and thus defaults to 0). + return false; + } + + upb_MiniTableSubInternal* table_sub = + UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + *table_sub = upb_MiniTableSub_FromEnum(sub); + return true; +} + +uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* m, + const upb_MiniTableField** subs) { + uint32_t msg_count = 0; + uint32_t enum_count = 0; + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { + *subs = f; + ++subs; + msg_count++; + } + } + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_IsClosedEnum(f)) { + *subs = f; + ++subs; + enum_count++; + } + } + + return (msg_count << 16) | enum_count; +} + +// The list of sub_tables and sub_enums must exactly match the number and order +// of sub-message fields and sub-enum fields given by upb_MiniTable_GetSubList() +// above. +bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables, + size_t sub_table_count, + const upb_MiniTableEnum** sub_enums, + size_t sub_enum_count) { + uint32_t msg_count = 0; + uint32_t enum_count = 0; + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + upb_MiniTableField* f = + (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { + const upb_MiniTable* sub = sub_tables[msg_count++]; + if (msg_count > sub_table_count) return false; + if (sub && !upb_MiniTable_SetSubMessage(m, f, sub)) return false; + } + } + + for (int i = 0; i < upb_MiniTable_FieldCount(m); i++) { + upb_MiniTableField* f = + (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); + if (upb_MiniTableField_IsClosedEnum(f)) { + const upb_MiniTableEnum* sub = sub_enums[enum_count++]; + if (enum_count > sub_enum_count) return false; + if (sub && !upb_MiniTable_SetSubEnum(m, f, sub)) return false; + } + } + + return (msg_count == sub_table_count) && (enum_count == sub_enum_count); +} + + +const char _kUpb_ToBase92[] = { + ' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', + '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', + 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '{', '|', '}', '~', +}; + +const int8_t _kUpb_FromBase92[] = { + 0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, -1, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +}; + + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +typedef struct { + uint64_t present_values_mask; + uint32_t last_written_value; +} upb_MtDataEncoderInternal_EnumState; + +typedef struct { + uint64_t msg_modifiers; + uint32_t last_field_num; + enum { + kUpb_OneofState_NotStarted, + kUpb_OneofState_StartedOneof, + kUpb_OneofState_EmittedOneofField, + } oneof_state; +} upb_MtDataEncoderInternal_MsgState; + +typedef struct { + char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize. + union { + upb_MtDataEncoderInternal_EnumState enum_state; + upb_MtDataEncoderInternal_MsgState msg_state; + } state; +} upb_MtDataEncoderInternal; + +static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal( + upb_MtDataEncoder* e, char* buf_start) { + UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal)); + upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal; + ret->buf_start = buf_start; + return ret; +} + +static char* upb_MtDataEncoder_PutRaw(upb_MtDataEncoder* e, char* ptr, + char ch) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize); + if (ptr == e->end) return NULL; + *ptr++ = ch; + return ptr; +} + +static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) { + return upb_MtDataEncoder_PutRaw(e, ptr, _upb_ToBase92(ch)); +} + +static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr, + uint32_t val, int min, int max) { + int shift = upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min) + 1); + UPB_ASSERT(shift <= 6); + uint32_t mask = (1 << shift) - 1; + do { + uint32_t bits = val & mask; + ptr = upb_MtDataEncoder_Put(e, ptr, bits + _upb_FromBase92(min)); + if (!ptr) return NULL; + val >>= shift; + } while (val); + return ptr; +} + +char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr, + uint64_t mod) { + if (mod) { + ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod, + kUpb_EncodedValue_MinModifier, + kUpb_EncodedValue_MaxModifier); + } + return ptr; +} + +char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.msg_state.msg_modifiers = 0; + in->state.msg_state.last_field_num = 0; + in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted; + + ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_ExtensionV1); + if (!ptr) return NULL; + + return upb_MtDataEncoder_PutField(e, ptr, type, field_num, field_mod); +} + +char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr, + upb_FieldType key_type, + upb_FieldType value_type, uint64_t key_mod, + uint64_t value_mod) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.msg_state.msg_modifiers = 0; + in->state.msg_state.last_field_num = 0; + in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted; + + ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MapV1); + if (!ptr) return NULL; + + ptr = upb_MtDataEncoder_PutField(e, ptr, key_type, 1, key_mod); + if (!ptr) return NULL; + + return upb_MtDataEncoder_PutField(e, ptr, value_type, 2, value_mod); +} + +char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr) { + (void)upb_MtDataEncoder_GetInternal(e, ptr); + return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageSetV1); +} + +char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr, + uint64_t msg_mod) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.msg_state.msg_modifiers = msg_mod; + in->state.msg_state.last_field_num = 0; + in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted; + + ptr = upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_MessageV1); + if (!ptr) return NULL; + + return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod); +} + +static char* _upb_MtDataEncoder_MaybePutFieldSkip(upb_MtDataEncoder* e, + char* ptr, + uint32_t field_num) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + if (field_num <= in->state.msg_state.last_field_num) return NULL; + if (in->state.msg_state.last_field_num + 1 != field_num) { + // Put skip. + UPB_ASSERT(field_num > in->state.msg_state.last_field_num); + uint32_t skip = field_num - in->state.msg_state.last_field_num; + ptr = upb_MtDataEncoder_PutBase92Varint( + e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip); + if (!ptr) return NULL; + } + in->state.msg_state.last_field_num = field_num; + return ptr; +} + +static char* _upb_MtDataEncoder_PutFieldType(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, + uint64_t field_mod) { + static const char kUpb_TypeToEncoded[] = { + [kUpb_FieldType_Double] = kUpb_EncodedType_Double, + [kUpb_FieldType_Float] = kUpb_EncodedType_Float, + [kUpb_FieldType_Int64] = kUpb_EncodedType_Int64, + [kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64, + [kUpb_FieldType_Int32] = kUpb_EncodedType_Int32, + [kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64, + [kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32, + [kUpb_FieldType_Bool] = kUpb_EncodedType_Bool, + [kUpb_FieldType_String] = kUpb_EncodedType_String, + [kUpb_FieldType_Group] = kUpb_EncodedType_Group, + [kUpb_FieldType_Message] = kUpb_EncodedType_Message, + [kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes, + [kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32, + [kUpb_FieldType_Enum] = kUpb_EncodedType_OpenEnum, + [kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32, + [kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64, + [kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32, + [kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64, + }; + + int encoded_type = kUpb_TypeToEncoded[type]; + + if (field_mod & kUpb_FieldModifier_IsClosedEnum) { + UPB_ASSERT(type == kUpb_FieldType_Enum); + encoded_type = kUpb_EncodedType_ClosedEnum; + } + + if (field_mod & kUpb_FieldModifier_IsRepeated) { + // Repeated fields shift the type number up (unlike other modifiers which + // are bit flags). + encoded_type += kUpb_EncodedType_RepeatedBase; + } + + return upb_MtDataEncoder_Put(e, ptr, encoded_type); +} + +static char* _upb_MtDataEncoder_MaybePutModifiers(upb_MtDataEncoder* e, + char* ptr, upb_FieldType type, + uint64_t field_mod) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + uint32_t encoded_modifiers = 0; + if ((field_mod & kUpb_FieldModifier_IsRepeated) && + upb_FieldType_IsPackable(type)) { + bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked; + bool default_is_packed = in->state.msg_state.msg_modifiers & + kUpb_MessageModifier_DefaultIsPacked; + if (field_is_packed != default_is_packed) { + encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked; + } + } + + if (type == kUpb_FieldType_String) { + bool field_validates_utf8 = field_mod & kUpb_FieldModifier_ValidateUtf8; + bool message_validates_utf8 = + in->state.msg_state.msg_modifiers & kUpb_MessageModifier_ValidateUtf8; + if (field_validates_utf8 != message_validates_utf8) { + // Old binaries do not recognize the field modifier. We need the failure + // mode to be too lax rather than too strict. Our caller should have + // handled this (see _upb_MessageDef_ValidateUtf8()). + assert(!message_validates_utf8); + encoded_modifiers |= kUpb_EncodedFieldModifier_FlipValidateUtf8; + } + } + + if (field_mod & kUpb_FieldModifier_IsProto3Singular) { + encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular; + } + + if (field_mod & kUpb_FieldModifier_IsRequired) { + encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired; + } + + return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers); +} + +char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod) { + upb_MtDataEncoder_GetInternal(e, ptr); + + ptr = _upb_MtDataEncoder_MaybePutFieldSkip(e, ptr, field_num); + if (!ptr) return NULL; + + ptr = _upb_MtDataEncoder_PutFieldType(e, ptr, type, field_mod); + if (!ptr) return NULL; + + return _upb_MtDataEncoder_MaybePutModifiers(e, ptr, type, field_mod); +} + +char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) { + ptr = upb_MtDataEncoder_Put(e, ptr, _upb_FromBase92(kUpb_EncodedValue_End)); + } else { + ptr = upb_MtDataEncoder_Put( + e, ptr, _upb_FromBase92(kUpb_EncodedValue_OneofSeparator)); + } + in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof; + return ptr; +} + +char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr, + uint32_t field_num) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) { + ptr = upb_MtDataEncoder_Put( + e, ptr, _upb_FromBase92(kUpb_EncodedValue_FieldSeparator)); + if (!ptr) return NULL; + } + ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, _upb_ToBase92(0), + _upb_ToBase92(63)); + in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField; + return ptr; +} + +char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + in->state.enum_state.present_values_mask = 0; + in->state.enum_state.last_written_value = 0; + + return upb_MtDataEncoder_PutRaw(e, ptr, kUpb_EncodedVersion_EnumV1); +} + +static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e, + char* ptr) { + upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal; + ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask); + in->state.enum_state.present_values_mask = 0; + in->state.enum_state.last_written_value += 5; + return ptr; +} + +char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr, + uint32_t val) { + // TODO: optimize this encoding. + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + UPB_ASSERT(val >= in->state.enum_state.last_written_value); + uint32_t delta = val - in->state.enum_state.last_written_value; + if (delta >= 5 && in->state.enum_state.present_values_mask) { + ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr); + if (!ptr) { + return NULL; + } + delta -= 5; + } + + if (delta >= 5) { + ptr = upb_MtDataEncoder_PutBase92Varint( + e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip); + in->state.enum_state.last_written_value += delta; + delta = 0; + } + + UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0); + in->state.enum_state.present_values_mask |= 1ULL << delta; + return ptr; +} + +char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) { + upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr); + if (!in->state.enum_state.present_values_mask) return ptr; + return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr); +} + + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +struct upb_ExtensionRegistry { + upb_exttable exts; + upb_Arena* arena; +}; + +upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { + upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r)); + if (!r) return NULL; + r->arena = arena; + if (!upb_exttable_init(&r->exts, 8, arena)) return NULL; + return r; +} + +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) { + UPB_STATIC_ASSERT( + offsetof(upb_MiniTableExtension, + UPB_PRIVATE(field).UPB_PRIVATE(number)) == 0, + "Extension must be first-member-of-struct convertable with uint32_t"); + uint32_t fieldnum = upb_MiniTableExtension_Number(e); + const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(e); + + const uint32_t kMaxFieldNumber = (1 << 29) - 1; + if (fieldnum == 0 || + (fieldnum > kMaxFieldNumber && !upb_MiniTable_IsMessageSet(extendee))) { + return kUpb_ExtensionRegistryStatus_InvalidExtension; + } + + if (upb_exttable_lookup(&r->exts, extendee, fieldnum) != NULL) { + return kUpb_ExtensionRegistryStatus_DuplicateEntry; + } + + if (!upb_exttable_insert(&r->exts, extendee, (const uint32_t*)e, r->arena)) { + return kUpb_ExtensionRegistryStatus_OutOfMemory; + } + return kUpb_ExtensionRegistryStatus_Ok; +} + +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count) { + const upb_MiniTableExtension** start = e; + const upb_MiniTableExtension** end = UPB_PTRADD(e, count); + upb_ExtensionRegistryStatus status = kUpb_ExtensionRegistryStatus_Ok; + for (; e < end; e++) { + status = upb_ExtensionRegistry_Add(r, *e); + if (status != kUpb_ExtensionRegistryStatus_Ok) goto failure; + } + return kUpb_ExtensionRegistryStatus_Ok; + +failure: + // Back out the entries previously added. + for (end = e, e = start; e < end; e++) { + const upb_MiniTableExtension* ext = *e; + upb_exttable_remove(&r->exts, upb_MiniTableExtension_Extendee(ext), + upb_MiniTableExtension_Number(ext)); + } + UPB_ASSERT(status != kUpb_ExtensionRegistryStatus_Ok); + return status; +} + +const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( + const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) { + const uint32_t* v = upb_exttable_lookup(&r->exts, t, num); + return (const upb_MiniTableExtension*)v; +} + +size_t upb_ExtensionRegistry_Size(const upb_ExtensionRegistry* r) { + return upb_exttable_size(&r->exts); +} + + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#if UPB_TSAN +#include <sched.h> +#endif // UPB_TSAN + +const UPB_PRIVATE(upb_GeneratedExtensionListEntry) * + UPB_PRIVATE(upb_generated_extension_list) = NULL; + +typedef struct upb_GeneratedRegistry { + UPB_ATOMIC(upb_GeneratedRegistryRef*) ref; + UPB_ATOMIC(int32_t) ref_count; +} upb_GeneratedRegistry; + +static upb_GeneratedRegistry* _upb_generated_registry(void) { + static upb_GeneratedRegistry r = {NULL, 0}; + return &r; +} + +static bool _upb_GeneratedRegistry_AddAllLinkedExtensions( + upb_ExtensionRegistry* r) { + const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* entry = + UPB_PRIVATE(upb_generated_extension_list); + while (entry != NULL) { + const upb_MiniTableExtension** current = entry->start; + for (current = entry->start; current != entry->stop; ++current) { + const upb_MiniTableExtension* ext = *current; + // Sentinels and padding introduced by the linker can result in zeroed + // entries, so simply skip them. + if (*current == NULL) { + // MSVC introduces padding that might not be sized exactly the same as + // the linker array element, but it should be properly aligned, so just + // skipping empty elements should be safe. (If the size and align of + // the array elements was different, we'd have to do something more + // complicated). + continue; + } + + if (upb_ExtensionRegistry_Add(r, ext) != + kUpb_ExtensionRegistryStatus_Ok) { + return false; + } + } + entry = entry->next; + } + return true; +} + +// Constructs a new GeneratedRegistryRef, adding all linked extensions to the +// registry or returning NULL on failure. +static upb_GeneratedRegistryRef* _upb_GeneratedRegistry_New(void) { + upb_Arena* arena = NULL; + upb_ExtensionRegistry* extreg = NULL; + upb_GeneratedRegistryRef* ref = upb_gmalloc(sizeof(upb_GeneratedRegistryRef)); + if (ref == NULL) goto err; + arena = upb_Arena_New(); + if (arena == NULL) goto err; + extreg = upb_ExtensionRegistry_New(arena); + if (extreg == NULL) goto err; + + ref->UPB_PRIVATE(arena) = arena; + ref->UPB_PRIVATE(registry) = extreg; + + if (!_upb_GeneratedRegistry_AddAllLinkedExtensions(extreg)) goto err; + + return ref; + +err: + if (arena != NULL) upb_Arena_Free(arena); + if (ref != NULL) upb_gfree(ref); + return NULL; +} + +const upb_GeneratedRegistryRef* upb_GeneratedRegistry_Load(void) { + upb_GeneratedRegistry* registry = _upb_generated_registry(); + + // Loop until we successfully acquire a reference. This loop should only + // kick in under extremely high contention, and it should be guaranteed to + // succeed. + while (true) { + int32_t count = upb_Atomic_Load(®istry->ref_count, memory_order_acquire); + + // Try to increment the refcount, but only if it's not zero. + while (count > 0) { + if (upb_Atomic_CompareExchangeStrong(®istry->ref_count, &count, + count + 1, memory_order_acquire, + memory_order_relaxed)) { + // Successfully incremented. We can now safely load and return the + // pointer. + const upb_GeneratedRegistryRef* ref = + upb_Atomic_Load(®istry->ref, memory_order_acquire); + UPB_ASSERT(ref != NULL); + return ref; + } + // CAS failed, `count` was updated. Loop will retry. + } + + // If we're here, the count was 0. Time for the slow path. + // Double-check that the pointer is NULL before trying to create. + upb_GeneratedRegistryRef* ref = + upb_Atomic_Load(®istry->ref, memory_order_acquire); + if (ref == NULL) { + // Pointer is NULL, try to create and publish a new registry. + upb_GeneratedRegistryRef* new_ref = _upb_GeneratedRegistry_New(); + if (new_ref == NULL) return NULL; // OOM + + // Try to CAS the pointer from NULL to our new_ref. + if (upb_Atomic_CompareExchangeStrong(®istry->ref, &ref, new_ref, + memory_order_release, + memory_order_acquire)) { + // We won the race. Set the ref count to 1. + upb_Atomic_Store(®istry->ref_count, 1, memory_order_release); + return new_ref; + } else { + // We lost the race. `ref` now holds the pointer from the winning + // thread. Clean up our unused one and loop to try again to get a + // reference. + upb_Arena_Free(new_ref->UPB_PRIVATE(arena)); + upb_gfree(new_ref); + } + } + // If we are here, either we lost the CAS race, or the pointer was already + // non-NULL. In either case, we loop to the top and try to increment the + // refcount of the existing object. + +#if UPB_TSAN + // Yield to give other threads a chance to increment the refcount. This is + // especially an issue for TSAN builds, which are prone to locking up from + // the thread with the upb_Atomic_Store call above getting starved. + sched_yield(); +#endif // UPB_TSAN + } +} + +void upb_GeneratedRegistry_Release(const upb_GeneratedRegistryRef* r) { + if (r == NULL) return; + + upb_GeneratedRegistry* registry = _upb_generated_registry(); + + int ref_count = upb_Atomic_Sub(®istry->ref_count, 1, memory_order_acq_rel); + UPB_ASSERT(registry->ref_count >= 0); + + // A ref_count of 1 means that we decremented the refcount to 0. + if (ref_count == 1) { + upb_GeneratedRegistryRef* ref = + upb_Atomic_Exchange(®istry->ref, NULL, memory_order_acq_rel); + if (ref != NULL) { + // This is the last reference and we won any potential race to store NULL, + // so we need to clean up. + upb_Arena_Free(ref->UPB_PRIVATE(arena)); + upb_gfree(ref); + } + } +} + +const upb_ExtensionRegistry* upb_GeneratedRegistry_Get( + const upb_GeneratedRegistryRef* r) { + if (r == NULL) return NULL; + return r->UPB_PRIVATE(registry); +} + + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f) { + if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) { + return NULL; + } + const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + for (; ptr < end; ptr++) { + if (ptr->presence == (*f).presence) { + return ptr; + } + } + return NULL; +} + +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f) { + const upb_MiniTableField* ptr = *f; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + while (++ptr < end) { + if (ptr->presence == (*f)->presence) { + *f = ptr; + return true; + } + } + return false; +} + + +#include <stddef.h> + + +// Must be last. + +// A MiniTable for a statically tree shaken message. Messages that use this +// MiniTable are guaranteed to remain unlinked; unlike the empty message, this +// MiniTable is never replaced, which greatly simplifies everything, because the +// type of a sub-message is always known, without consulting a tagged bit. +const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_StaticallyTreeShaken) = { + .UPB_PRIVATE(fields) = NULL, + .UPB_PRIVATE(size) = sizeof(struct upb_Message), + .UPB_PRIVATE(field_count) = 0, + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, + .UPB_PRIVATE(dense_below) = 0, + .UPB_PRIVATE(table_mask) = -1, + .UPB_PRIVATE(required_count) = 0, +}; + + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + + +// Must be last. + +struct upb_DefPool { + upb_Arena* arena; + upb_strtable syms; // full_name -> packed def ptr + upb_strtable files; // file_name -> (upb_FileDef*) + upb_inttable exts; // (upb_MiniTableExtension*) -> (upb_FieldDef*) + upb_ExtensionRegistry* extreg; + const upb_GeneratedRegistryRef* generated_extreg; + const google_protobuf_FeatureSetDefaults* feature_set_defaults; + upb_MiniTablePlatform platform; + void* scratch_data; + size_t scratch_size; + size_t bytes_loaded; + bool disable_closed_enum_checking; + bool disable_implicit_field_presence; +}; + +void upb_DefPool_Free(upb_DefPool* s) { + upb_GeneratedRegistry_Release(s->generated_extreg); + upb_Arena_Free(s->arena); + upb_gfree(s->scratch_data); + upb_gfree(s); +} + +static const char serialized_defaults[] = UPB_INTERNAL_UPB_EDITION_DEFAULTS; + +upb_DefPool* upb_DefPool_New(void) { + upb_DefPool* s = upb_gmalloc(sizeof(*s)); + if (!s) return NULL; + + s->arena = upb_Arena_New(); + s->bytes_loaded = 0; + s->disable_closed_enum_checking = false; + s->disable_implicit_field_presence = false; + + s->scratch_size = 240; + s->scratch_data = upb_gmalloc(s->scratch_size); + if (!s->scratch_data) goto err; + + if (!upb_strtable_init(&s->syms, 32, s->arena)) goto err; + if (!upb_strtable_init(&s->files, 4, s->arena)) goto err; + if (!upb_inttable_init(&s->exts, s->arena)) goto err; + + s->extreg = upb_ExtensionRegistry_New(s->arena); + if (!s->extreg) goto err; + + s->generated_extreg = upb_GeneratedRegistry_Load(); + if (!s->generated_extreg) goto err; + + s->platform = kUpb_MiniTablePlatform_Native; + + upb_Status status; + if (!upb_DefPool_SetFeatureSetDefaults( + s, serialized_defaults, sizeof(serialized_defaults) - 1, &status)) { + goto err; + } + + if (!s->feature_set_defaults) goto err; + + return s; + +err: + upb_DefPool_Free(s); + return NULL; +} + +void upb_DefPool_DisableClosedEnumChecking(upb_DefPool* s) { + UPB_ASSERT(upb_strtable_count(&s->files) == 0); + s->disable_closed_enum_checking = true; +} + +bool upb_DefPool_ClosedEnumCheckingDisabled(const upb_DefPool* s) { + return s->disable_closed_enum_checking; +} + +void upb_DefPool_DisableImplicitFieldPresence(upb_DefPool* s) { + UPB_ASSERT(upb_strtable_count(&s->files) == 0); + s->disable_implicit_field_presence = true; +} + +bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s) { + return s->disable_implicit_field_presence; +} + +const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults( + const upb_DefPool* s) { + return s->feature_set_defaults; +} + +bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status) { + const google_protobuf_FeatureSetDefaults* defaults = google_protobuf_FeatureSetDefaults_parse( + serialized_defaults, serialized_len, s->arena); + if (!defaults) { + upb_Status_SetErrorFormat(status, "Failed to parse defaults"); + return false; + } + if (upb_strtable_count(&s->files) > 0) { + upb_Status_SetErrorFormat(status, + "Feature set defaults can't be changed once the " + "pool has started building"); + return false; + } + int min_edition = google_protobuf_FeatureSetDefaults_minimum_edition(defaults); + int max_edition = google_protobuf_FeatureSetDefaults_maximum_edition(defaults); + if (min_edition > max_edition) { + upb_Status_SetErrorFormat(status, "Invalid edition range %s to %s", + upb_FileDef_EditionName(min_edition), + upb_FileDef_EditionName(max_edition)); + return false; + } + size_t size; + const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* + default_list = google_protobuf_FeatureSetDefaults_defaults(defaults, &size); + int prev_edition = google_protobuf_EDITION_UNKNOWN; + for (size_t i = 0; i < size; ++i) { + int edition = google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition( + default_list[i]); + if (edition == google_protobuf_EDITION_UNKNOWN) { + upb_Status_SetErrorFormat(status, "Invalid edition UNKNOWN specified"); + return false; + } + if (edition <= prev_edition) { + upb_Status_SetErrorFormat(status, + "Feature set defaults are not strictly " + "increasing, %s is greater than or equal to %s", + upb_FileDef_EditionName(prev_edition), + upb_FileDef_EditionName(edition)); + return false; + } + prev_edition = edition; + } + + // Copy the defaults into the pool. + s->feature_set_defaults = defaults; + return true; +} + +bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext, + const upb_FieldDef* f) { + return upb_inttable_insert(&s->exts, (uintptr_t)ext, upb_value_constptr(f), + s->arena); +} + +bool _upb_DefPool_InsertSym(upb_DefPool* s, upb_StringView sym, upb_value v, + upb_Status* status) { + // TODO: table should support an operation "tryinsert" to avoid the double + // lookup. + if (upb_strtable_lookup2(&s->syms, sym.data, sym.size, NULL)) { + upb_Status_SetErrorFormat(status, "duplicate symbol '%s'", sym.data); + return false; + } + if (!upb_strtable_insert(&s->syms, sym.data, sym.size, v, s->arena)) { + upb_Status_SetErrorMessage(status, "out of memory"); + return false; + } + return true; +} + +static const void* _upb_DefPool_Unpack(const upb_DefPool* s, const char* sym, + size_t size, upb_deftype_t type) { + upb_value v; + return upb_strtable_lookup2(&s->syms, sym, size, &v) + ? _upb_DefType_Unpack(v, type) + : NULL; +} + +bool _upb_DefPool_LookupSym(const upb_DefPool* s, const char* sym, size_t size, + upb_value* v) { + return upb_strtable_lookup2(&s->syms, sym, size, v); +} + +upb_ExtensionRegistry* _upb_DefPool_ExtReg(const upb_DefPool* s) { + return s->extreg; +} + +void** _upb_DefPool_ScratchData(const upb_DefPool* s) { + return (void**)&s->scratch_data; +} + +size_t* _upb_DefPool_ScratchSize(const upb_DefPool* s) { + return (size_t*)&s->scratch_size; +} + +void _upb_DefPool_SetPlatform(upb_DefPool* s, upb_MiniTablePlatform platform) { + assert(upb_strtable_count(&s->files) == 0); + s->platform = platform; +} + +const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindMessageByNameWithSize(s, sym, strlen(sym)); +} + +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len) { + return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_MSG); +} + +const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindEnumByNameWithSize(s, sym, strlen(sym)); +} + +const upb_EnumDef* upb_DefPool_FindEnumByNameWithSize(const upb_DefPool* s, + const char* sym, + size_t len) { + return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUM); +} + +const upb_EnumValueDef* upb_DefPool_FindEnumValueByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindEnumValueByNameWithSize(s, sym, strlen(sym)); +} + +const upb_EnumValueDef* upb_DefPool_FindEnumValueByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len) { + return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUMVAL); +} + +const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name) { + upb_value v; + return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) + : NULL; +} + +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len) { + upb_value v; + return upb_strtable_lookup2(&s->files, name, len, &v) + ? upb_value_getconstptr(v) + : NULL; +} + +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { + upb_value v; + if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL; + + switch (_upb_DefType_Type(v)) { + case UPB_DEFTYPE_FIELD: + return _upb_DefType_Unpack(v, UPB_DEFTYPE_FIELD); + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = _upb_DefType_Unpack(v, UPB_DEFTYPE_MSG); + if (_upb_MessageDef_InMessageSet(m)) { + for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { + const upb_FieldDef* ext = upb_MessageDef_NestedExtension(m, i); + if (upb_FieldDef_MessageSubDef(ext) == m) { + return ext; + } + } + } + return NULL; + } + default: + break; + } + + return NULL; +} + +const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, + const char* sym) { + return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym)); +} + +const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, + const char* name) { + return _upb_DefPool_Unpack(s, name, strlen(name), UPB_DEFTYPE_SERVICE); +} + +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size) { + return _upb_DefPool_Unpack(s, name, size, UPB_DEFTYPE_SERVICE); +} + +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name) { + upb_value v; + // TODO: non-extension fields and oneofs. + if (upb_strtable_lookup(&s->syms, name, &v)) { + switch (_upb_DefType_Type(v)) { + case UPB_DEFTYPE_EXT: { + const upb_FieldDef* f = _upb_DefType_Unpack(v, UPB_DEFTYPE_EXT); + return upb_FieldDef_File(f); + } + case UPB_DEFTYPE_MSG: { + const upb_MessageDef* m = _upb_DefType_Unpack(v, UPB_DEFTYPE_MSG); + return upb_MessageDef_File(m); + } + case UPB_DEFTYPE_ENUM: { + const upb_EnumDef* e = _upb_DefType_Unpack(v, UPB_DEFTYPE_ENUM); + return upb_EnumDef_File(e); + } + case UPB_DEFTYPE_ENUMVAL: { + const upb_EnumValueDef* ev = + _upb_DefType_Unpack(v, UPB_DEFTYPE_ENUMVAL); + return upb_EnumDef_File(upb_EnumValueDef_Enum(ev)); + } + case UPB_DEFTYPE_SERVICE: { + const upb_ServiceDef* service = + _upb_DefType_Unpack(v, UPB_DEFTYPE_SERVICE); + return upb_ServiceDef_File(service); + } + default: + UPB_UNREACHABLE(); + } + } + + const char* last_dot = strrchr(name, '.'); + if (last_dot) { + const upb_MessageDef* parent = + upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name); + if (parent) { + const char* shortname = last_dot + 1; + if (upb_MessageDef_FindByNameWithSize(parent, shortname, + strlen(shortname), NULL, NULL)) { + return upb_MessageDef_File(parent); + } + } + } + + return NULL; +} + +static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { + intptr_t iter = UPB_INTTABLE_BEGIN; + upb_StringView key; + upb_value val; + while (upb_strtable_next2(&s->syms, &key, &val, &iter)) { + const upb_FileDef* f; + switch (_upb_DefType_Type(val)) { + case UPB_DEFTYPE_EXT: + f = upb_FieldDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_EXT)); + break; + case UPB_DEFTYPE_MSG: + f = upb_MessageDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_MSG)); + break; + case UPB_DEFTYPE_ENUM: + f = upb_EnumDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_ENUM)); + break; + case UPB_DEFTYPE_ENUMVAL: + f = upb_EnumDef_File(upb_EnumValueDef_Enum( + _upb_DefType_Unpack(val, UPB_DEFTYPE_ENUMVAL))); + break; + case UPB_DEFTYPE_SERVICE: + f = upb_ServiceDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_SERVICE)); + break; + default: + UPB_UNREACHABLE(); + } + + if (f == file) upb_strtable_removeiter(&s->syms, &iter); + } +} + +static const upb_FileDef* upb_DefBuilder_AddFileToPool( + upb_DefBuilder* const builder, upb_DefPool* const s, + const google_protobuf_FileDescriptorProto* const file_proto, + const upb_StringView name, upb_Status* const status) { + if (UPB_SETJMP(builder->err) != 0) { + UPB_ASSERT(!upb_Status_IsOk(status)); + if (builder->file) { + remove_filedef(s, builder->file); + builder->file = NULL; + } + } else if (!builder->arena || !builder->tmp_arena || + !upb_strtable_init(&builder->feature_cache, 16, + builder->tmp_arena) || + !(builder->legacy_features = + google_protobuf_FeatureSet_new(builder->tmp_arena))) { + _upb_DefBuilder_OomErr(builder); + } else { + _upb_FileDef_Create(builder, file_proto); + upb_strtable_insert(&s->files, name.data, name.size, + upb_value_constptr(builder->file), builder->arena); + UPB_ASSERT(upb_Status_IsOk(status)); + upb_Arena_Fuse(s->arena, builder->arena); + } + + if (builder->arena) upb_Arena_Free(builder->arena); + if (builder->tmp_arena) upb_Arena_Free(builder->tmp_arena); + return builder->file; +} + +static const upb_FileDef* _upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + const upb_MiniTableFile* layout, upb_Status* status) { + const upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); + + // Determine whether we already know about this file. + { + upb_value v; + if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) { + upb_Status_SetErrorFormat(status, + "duplicate file name " UPB_STRINGVIEW_FORMAT, + UPB_STRINGVIEW_ARGS(name)); + return NULL; + } + } + + upb_DefBuilder ctx = { + .symtab = s, + .tmp_buf = NULL, + .tmp_buf_size = 0, + .layout = layout, + .platform = s->platform, + .msg_count = 0, + .enum_count = 0, + .ext_count = 0, + .status = status, + .file = NULL, + .arena = upb_Arena_New(), + .tmp_arena = upb_Arena_New(), + }; + + return upb_DefBuilder_AddFileToPool(&ctx, s, file_proto, name, status); +} + +const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + upb_Status* status) { + return _upb_DefPool_AddFile(s, file_proto, NULL, status); +} + +bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable) { + /* Since this function should never fail (it would indicate a bug in upb) we + * print errors to stderr instead of returning error status to the user. */ + _upb_DefPool_Init** deps = init->deps; + google_protobuf_FileDescriptorProto* file; + upb_Arena* arena; + upb_Status status; + + upb_Status_Clear(&status); + + if (upb_DefPool_FindFileByName(s, init->filename)) { + return true; + } + + arena = upb_Arena_New(); + + for (; *deps; deps++) { + if (!_upb_DefPool_LoadDefInitEx(s, *deps, rebuild_minitable)) goto err; + } + + file = google_protobuf_FileDescriptorProto_parse_ex( + init->descriptor.data, init->descriptor.size, NULL, + kUpb_DecodeOption_AliasString, arena); + s->bytes_loaded += init->descriptor.size; + + if (!file) { + upb_Status_SetErrorFormat( + &status, + "Failed to parse compiled-in descriptor for file '%s'. This should " + "never happen.", + init->filename); + goto err; + } + + const upb_MiniTableFile* mt = rebuild_minitable ? NULL : init->layout; + if (!_upb_DefPool_AddFile(s, file, mt, &status)) { + goto err; + } + + upb_Arena_Free(arena); + return true; + +err: + fprintf(stderr, + "Error loading compiled-in descriptor for file '%s' (this should " + "never happen): %s\n", + init->filename, upb_Status_ErrorMessage(&status)); + upb_Arena_Free(arena); + return false; +} + +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) { + return s->bytes_loaded; +} + +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; } + +const upb_FieldDef* upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTableExtension* ext) { + upb_value v; + bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v); + UPB_ASSERT(ok); + return upb_value_getconstptr(v); +} + +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum) { + const upb_MiniTable* t = upb_MessageDef_MiniTable(m); + const upb_MiniTableExtension* ext = + upb_ExtensionRegistry_Lookup(s->extreg, t, fieldnum); + return ext ? upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL; +} + +const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s) { + return s->extreg; +} + +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count) { + size_t n = 0; + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t key; + upb_value val; + // This is O(all exts) instead of O(exts for m). If we need this to be + // efficient we may need to make extreg into a two-level table, or have a + // second per-message index. + while (upb_inttable_next(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) n++; + } + const upb_FieldDef** exts = upb_gmalloc(n * sizeof(*exts)); + iter = UPB_INTTABLE_BEGIN; + size_t i = 0; + while (upb_inttable_next(&s->exts, &key, &val, &iter)) { + const upb_FieldDef* f = upb_value_getconstptr(val); + if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f; + } + *count = n; + return exts; +} + +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) { + return _upb_DefPool_LoadDefInitEx(s, init, false); +} + +const upb_ExtensionRegistry* _upb_DefPool_GeneratedExtensionRegistry( + const upb_DefPool* s) { + return upb_GeneratedRegistry_Get(s->generated_extreg); +} + + +// Must be last. + +upb_deftype_t _upb_DefType_Type(upb_value v) { + const uintptr_t num = (uintptr_t)upb_value_getconstptr(v); + return num & UPB_DEFTYPE_MASK; +} + +upb_value _upb_DefType_Pack(const void* ptr, upb_deftype_t type) { + uintptr_t num = (uintptr_t)ptr; + UPB_ASSERT((num & UPB_DEFTYPE_MASK) == 0); + num |= type; + return upb_value_constptr((const void*)num); +} + +const void* _upb_DefType_Unpack(upb_value v, upb_deftype_t type) { + uintptr_t num = (uintptr_t)upb_value_getconstptr(v); + return (num & UPB_DEFTYPE_MASK) == type + ? (const void*)(num & ~UPB_DEFTYPE_MASK) + : NULL; +} + + +// Must be last. + +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; +} + + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +struct upb_EnumDef { + UPB_ALIGN_AS(8) const google_protobuf_EnumOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_MiniTableEnum* layout; // Only for proto2. + const upb_FileDef* file; + const upb_MessageDef* containing_type; // Could be merged with "file". + const char* full_name; + upb_strtable ntoi; + upb_inttable iton; + const upb_EnumValueDef* values; + const upb_EnumReservedRange* res_ranges; + const upb_StringView* res_names; + int value_count; + int res_range_count; + int res_name_count; + int32_t defaultval; + google_protobuf_SymbolVisibility visibility; + bool is_sorted; // Whether all of the values are defined in ascending order. +}; + +upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { + return (upb_EnumDef*)&e[i]; +} + +const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) { + return e->layout; +} + +bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) { + const char* name = upb_EnumValueDef_Name(v); + const upb_value val = upb_value_constptr(v); + bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a); + if (!ok) return false; + + // Multiple enumerators can have the same number, first one wins. + const int number = upb_EnumValueDef_Number(v); + if (!upb_inttable_lookup(&e->iton, number, NULL)) { + return upb_inttable_insert(&e->iton, number, val, a); + } + return true; +} + +const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { + return e->opts; +} + +bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { + return e->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e) { + return e->resolved_features; +} + +google_protobuf_SymbolVisibility upb_EnumDef_Visibility(const upb_EnumDef* e) { + return e->visibility; +} + +const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } + +const char* upb_EnumDef_Name(const upb_EnumDef* e) { + return _upb_DefBuilder_FullToShort(e->full_name); +} + +const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; } + +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) { + return e->containing_type; +} + +int32_t upb_EnumDef_Default(const upb_EnumDef* e) { + UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval)); + return e->defaultval; +} + +int upb_EnumDef_ReservedRangeCount(const upb_EnumDef* e) { + return e->res_range_count; +} + +const upb_EnumReservedRange* upb_EnumDef_ReservedRange(const upb_EnumDef* e, + int i) { + UPB_ASSERT(0 <= i && i < e->res_range_count); + return _upb_EnumReservedRange_At(e->res_ranges, i); +} + +int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e) { + return e->res_name_count; +} + +upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) { + UPB_ASSERT(0 <= i && i < e->res_name_count); + return e->res_names[i]; +} + +int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } + +const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, + const char* name) { + return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); +} + +const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* e, const char* name, size_t size) { + upb_value v; + return upb_strtable_lookup2(&e->ntoi, name, size, &v) + ? upb_value_getconstptr(v) + : NULL; +} + +const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, + int32_t num) { + upb_value v; + return upb_inttable_lookup(&e->iton, num, &v) ? upb_value_getconstptr(v) + : NULL; +} + +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) { + // We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect + // this to be faster (especially for small numbers). + return upb_MiniTableEnum_CheckValue(e->layout, num); +} + +const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { + UPB_ASSERT(0 <= i && i < e->value_count); + return _upb_EnumValueDef_At(e->values, i); +} + +static bool upb_EnumDef_IsSpecifiedAsClosed(const upb_EnumDef* e) { + return google_protobuf_FeatureSet_enum_type(e->resolved_features) == + google_protobuf_FeatureSet_CLOSED; +} + +bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { + if (_upb_FileDef_ClosedEnumCheckingDisabled(e->file)) return false; + return upb_EnumDef_IsSpecifiedAsClosed(e); +} + +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; + } + + if (!_upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_StartEnum(&s.e, s.ptr); + + // Duplicate values are allowed but we only encode each value once. + uint32_t previous = 0; + + for (int 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_MiniTableEnum* create_enumlayout(upb_DefBuilder* ctx, + const upb_EnumDef* e) { + upb_StringView 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; + upb_MiniTableEnum* layout = + upb_MiniTableEnum_Build(sv.data, sv.size, ctx->arena, &status); + if (!layout) + _upb_DefBuilder_Errf(ctx, "Error building enum MiniTable: %s", status.msg); + return layout; +} + +static upb_StringView* _upb_EnumReservedNames_New( + upb_DefBuilder* ctx, int n, const upb_StringView* protos) { + upb_StringView* sv = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_StringView, n); + for (int i = 0; i < n; i++) { + sv[i].data = + upb_strdup2(protos[i].data, protos[i].size, _upb_DefBuilder_Arena(ctx)); + sv[i].size = protos[i].size; + } + return sv; +} + +static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_EnumDescriptorProto* enum_proto, + const google_protobuf_FeatureSet* parent_features, + upb_EnumDef* e) { + const google_protobuf_EnumValueDescriptorProto* const* values; + const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* res_ranges; + const upb_StringView* res_names; + upb_StringView name; + size_t n_value, n_res_range, n_res_name; + + UPB_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); + e->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_EnumOptions_features(e->opts)); + + // Must happen before _upb_DefBuilder_Add() + e->file = _upb_DefBuilder_File(ctx); + + name = google_protobuf_EnumDescriptorProto_name(enum_proto); + + e->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + _upb_DefBuilder_Add(ctx, e->full_name, + _upb_DefType_Pack(e, UPB_DEFTYPE_ENUM)); + + values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n_value); + + if (n_value == 0) { + _upb_DefBuilder_Errf(ctx, "enums must contain at least one value (%s)", + e->full_name); + } + + e->defaultval = google_protobuf_EnumValueDescriptorProto_number(values[0]); + + // When the special UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN is enabled, we have to + // exempt closed enums from this check, even when we are treating them as + // open. + // + // We rely on the fact that the proto compiler will have already ensured that + // implicit presence fields do not use closed enums, even if we are treating + // them as open. + if (!upb_EnumDef_IsSpecifiedAsClosed(e) && e->defaultval != 0) { + _upb_DefBuilder_Errf(ctx, + "for open enums, the first value must be zero (%s)", + upb_EnumDef_FullName(e)); + } + + bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_inttable_init(&e->iton, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + e->value_count = n_value; + e->values = _upb_EnumValueDefs_New(ctx, prefix, n_value, values, + e->resolved_features, e, &e->is_sorted); + + res_ranges = + google_protobuf_EnumDescriptorProto_reserved_range(enum_proto, &n_res_range); + e->res_range_count = n_res_range; + e->res_ranges = _upb_EnumReservedRanges_New(ctx, n_res_range, res_ranges, e); + + res_names = google_protobuf_EnumDescriptorProto_reserved_name(enum_proto, &n_res_name); + e->res_name_count = n_res_name; + e->res_names = _upb_EnumReservedNames_New(ctx, n_res_name, res_names); + + e->visibility = google_protobuf_EnumDescriptorProto_visibility(enum_proto); + + if (!upb_inttable_compact(&e->iton, ctx->arena)) _upb_DefBuilder_OomErr(ctx); + + if (upb_EnumDef_IsClosed(e)) { + if (ctx->layout) { + e->layout = upb_MiniTableFile_Enum(ctx->layout, ctx->enum_count++); + } else { + e->layout = create_enumlayout(ctx, e); + } + } else { + e->layout = NULL; + } +} + +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type) { + _upb_DefType_CheckPadding(sizeof(upb_EnumDef)); + + // If a containing type is defined then get the full name from that. + // Otherwise use the package name from the file def. + const char* name = containing_type ? upb_MessageDef_FullName(containing_type) + : _upb_FileDef_RawPackage(ctx->file); + + upb_EnumDef* e = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_EnumDef, n); + for (int i = 0; i < n; i++) { + create_enumdef(ctx, name, protos[i], parent_features, &e[i]); + e[i].containing_type = containing_type; + } + return e; +} + + +#include <stdint.h> + + +// Must be last. + +struct upb_EnumReservedRange { + int32_t start; + int32_t end; +}; + +upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r, + int i) { + return (upb_EnumReservedRange*)&r[i]; +} + +int32_t upb_EnumReservedRange_Start(const upb_EnumReservedRange* r) { + return r->start; +} +int32_t upb_EnumReservedRange_End(const upb_EnumReservedRange* r) { + return r->end; +} + +upb_EnumReservedRange* _upb_EnumReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos, + const upb_EnumDef* e) { + upb_EnumReservedRange* r = + UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_EnumReservedRange, n); + + for (int i = 0; i < n; i++) { + const int32_t start = + google_protobuf_EnumDescriptorProto_EnumReservedRange_start(protos[i]); + const int32_t end = + google_protobuf_EnumDescriptorProto_EnumReservedRange_end(protos[i]); + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + + // Note: Not a typo! Unlike extension ranges and message reserved ranges, + // the end value of an enum reserved range is *inclusive*! + if (end < start) { + _upb_DefBuilder_Errf(ctx, "Reserved range (%d, %d) is invalid, enum=%s\n", + (int)start, (int)end, upb_EnumDef_FullName(e)); + } + + r[i].start = start; + r[i].end = end; + } + + return r; +} + + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + + +// Must be last. + +struct upb_EnumValueDef { + UPB_ALIGN_AS(8) const google_protobuf_EnumValueOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_EnumDef* parent; + const char* full_name; + int32_t number; +}; + +upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i) { + return (upb_EnumValueDef*)&v[i]; +} + +static int _upb_EnumValueDef_Compare(const void* p1, const void* p2) { + const uint32_t v1 = (*(const upb_EnumValueDef**)p1)->number; + const uint32_t v2 = (*(const upb_EnumValueDef**)p2)->number; + return (v1 < v2) ? -1 : (v1 > v2); +} + +const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, + size_t n, upb_Arena* a) { + if (SIZE_MAX / sizeof(void*) < n) return NULL; + // TODO: Try to replace this arena alloc with a persistent scratch buffer. + upb_EnumValueDef** out = + (upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*)); + if (!out) return NULL; + + for (int i = 0; i < n; i++) { + out[i] = (upb_EnumValueDef*)&v[i]; + } + qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare); + + return (const upb_EnumValueDef**)out; +} + +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* v) { + return v->opts; +} + +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v) { + return v->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_EnumValueDef_ResolvedFeatures( + const upb_EnumValueDef* e) { + return e->resolved_features; +} + +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v) { + return v->parent; +} + +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) { + return v->full_name; +} + +const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) { + return _upb_DefBuilder_FullToShort(v->full_name); +} + +int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v) { return v->number; } + +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { + // Compute index in our parent's array. + return v - upb_EnumDef_Value(v->parent, 0); +} + +static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_EnumValueDescriptorProto* val_proto, + const google_protobuf_FeatureSet* parent_features, + upb_EnumDef* e, upb_EnumValueDef* v) { + UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, + val_proto); + v->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_EnumValueOptions_features(v->opts)); + + upb_StringView name = google_protobuf_EnumValueDescriptorProto_name(val_proto); + + v->parent = e; // Must happen prior to _upb_DefBuilder_Add() + v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + _upb_DefBuilder_Add(ctx, v->full_name, + _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); + + bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +// Allocate and initialize an array of |n| enum value defs owned by |e|. +upb_EnumValueDef* _upb_EnumValueDefs_New( + upb_DefBuilder* ctx, const char* prefix, int n, + const google_protobuf_EnumValueDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_EnumDef* e, bool* is_sorted) { + _upb_DefType_CheckPadding(sizeof(upb_EnumValueDef)); + + upb_EnumValueDef* v = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_EnumValueDef, n); + + *is_sorted = true; + uint32_t previous = 0; + for (int i = 0; i < n; i++) { + create_enumvaldef(ctx, prefix, protos[i], parent_features, e, &v[i]); + + const uint32_t current = v[i].number; + if (previous > current) *is_sorted = false; + previous = current; + } + + return v; +} + + +#include <stdint.h> + + +// Must be last. + +struct upb_ExtensionRange { + const google_protobuf_ExtensionRangeOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + int32_t start; + int32_t end; +}; + +upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i) { + return (upb_ExtensionRange*)&r[i]; +} + +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r) { + return r->opts; +} + +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) { + return r->opts != (void*)kUpbDefOptDefault; +} + +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r) { + return r->start; +} + +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r) { return r->end; } + +upb_ExtensionRange* _upb_ExtensionRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ExtensionRange* const* protos, + const google_protobuf_FeatureSet* parent_features, const upb_MessageDef* m) { + upb_ExtensionRange* r = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_ExtensionRange, n); + + for (int i = 0; i < n; i++) { + UPB_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, + ExtensionRangeOptions, protos[i]); + r[i].resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_ExtensionRangeOptions_features(r[i].opts)); + + const int32_t start = + google_protobuf_DescriptorProto_ExtensionRange_start(protos[i]); + const int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(protos[i]); + const int32_t max = + google_protobuf_MessageOptions_message_set_wire_format(upb_MessageDef_Options(m)) + ? INT32_MAX + : kUpb_MaxFieldNumber + 1; + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + if (start < 1 || end <= start || end > max) { + _upb_DefBuilder_Errf(ctx, + "Extension range (%d, %d) is invalid, message=%s\n", + (int)start, (int)end, upb_MessageDef_FullName(m)); + } + + r[i].start = start; + r[i].end = end; + } + + return r; +} + + +#include <ctype.h> +#include <errno.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Must be last. + +#define UPB_FIELD_TYPE_UNSPECIFIED 0 + +typedef struct { + size_t len; + char str[1]; // Null-terminated string data follows. +} str_t; + +struct upb_FieldDef { + UPB_ALIGN_AS(8) const google_protobuf_FieldOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_FileDef* file; + const upb_MessageDef* msgdef; + const char* full_name; + const char* json_name; + union { + int64_t sint; + uint64_t uint; + double dbl; + float flt; + bool boolean; + str_t* str; + void* msg; // Always NULL. + } defaultval; + union { + const upb_OneofDef* oneof; + const upb_MessageDef* extension_scope; + } scope; + union { + const upb_MessageDef* msgdef; + const upb_EnumDef* enumdef; + const google_protobuf_FieldDescriptorProto* unresolved; + } sub; + uint32_t number_; + uint16_t index_; + uint16_t layout_index; // Index into msgdef->layout->fields or file->exts + bool has_default; + bool has_json_name; + bool has_presence; + bool is_extension; + bool is_proto3_optional; + upb_FieldType type_; + upb_Label label_; +}; + +upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i) { + return (upb_FieldDef*)&f[i]; +} + +const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f) { + return f->opts; +} + +bool upb_FieldDef_HasOptions(const upb_FieldDef* f) { + return f->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f) { + return f->resolved_features; +} + +const char* upb_FieldDef_FullName(const upb_FieldDef* f) { + return f->full_name; +} + +upb_CType upb_FieldDef_CType(const upb_FieldDef* f) { + return upb_FieldType_CType(f->type_); +} + +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; } + +uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; } + +uint32_t upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { + return f->layout_index; +} + +upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; } + +uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } + +bool upb_FieldDef_IsExtension(const upb_FieldDef* f) { return f->is_extension; } + +bool _upb_FieldDef_IsPackable(const upb_FieldDef* f) { + return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsPrimitive(f); +} + +bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { + return _upb_FieldDef_IsPackable(f) && + google_protobuf_FeatureSet_repeated_field_encoding(f->resolved_features) == + google_protobuf_FeatureSet_PACKED; +} + +const char* upb_FieldDef_Name(const upb_FieldDef* f) { + return _upb_DefBuilder_FullToShort(f->full_name); +} + +const char* upb_FieldDef_JsonName(const upb_FieldDef* f) { + return f->json_name; +} + +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) { + return f->has_json_name; +} + +const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; } + +const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) { + return f->msgdef; +} + +const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) { + return f->is_extension ? f->scope.extension_scope : NULL; +} + +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) { + return f->is_extension ? NULL : f->scope.oneof; +} + +const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) { + const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(f); + if (!oneof || upb_OneofDef_IsSynthetic(oneof)) return NULL; + return oneof; +} + +upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f) { + upb_MessageValue ret; + + if (upb_FieldDef_IsRepeated(f) || upb_FieldDef_IsSubMessage(f)) { + return (upb_MessageValue){.msg_val = NULL}; + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return (upb_MessageValue){.bool_val = f->defaultval.boolean}; + case kUpb_CType_Int64: + return (upb_MessageValue){.int64_val = f->defaultval.sint}; + case kUpb_CType_UInt64: + return (upb_MessageValue){.uint64_val = f->defaultval.uint}; + case kUpb_CType_Enum: + case kUpb_CType_Int32: + return (upb_MessageValue){.int32_val = (int32_t)f->defaultval.sint}; + case kUpb_CType_UInt32: + return (upb_MessageValue){.uint32_val = (uint32_t)f->defaultval.uint}; + case kUpb_CType_Float: + return (upb_MessageValue){.float_val = f->defaultval.flt}; + case kUpb_CType_Double: + return (upb_MessageValue){.double_val = f->defaultval.dbl}; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + str_t* str = f->defaultval.str; + if (str) { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = str->str, .size = str->len}}; + } else { + return (upb_MessageValue){ + .str_val = (upb_StringView){.data = NULL, .size = 0}}; + } + } + default: + UPB_UNREACHABLE(); + } + + return ret; +} + +const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsSubMessage(f) ? f->sub.msgdef : NULL; +} + +const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsEnum(f) ? f->sub.enumdef : NULL; +} + +const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) { + if (upb_FieldDef_IsExtension(f)) { + const upb_FileDef* file = upb_FieldDef_File(f); + return (upb_MiniTableField*)_upb_FileDef_ExtensionMiniTable( + file, f->layout_index); + } else { + const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef); + return &layout->UPB_PRIVATE(fields)[f->layout_index]; + } +} + +const upb_MiniTableExtension* upb_FieldDef_MiniTableExtension( + const upb_FieldDef* f) { + UPB_ASSERT(upb_FieldDef_IsExtension(f)); + const upb_FileDef* file = upb_FieldDef_File(f); + return _upb_FileDef_ExtensionMiniTable(file, f->layout_index); +} + +bool _upb_FieldDef_IsClosedEnum(const upb_FieldDef* f) { + if (f->type_ != kUpb_FieldType_Enum) return false; + return upb_EnumDef_IsClosed(f->sub.enumdef); +} + +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) { + return f->is_proto3_optional; +} + +int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { return f->layout_index; } + +bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { + if (upb_FieldDef_Type(f) != kUpb_FieldType_String) return false; + return google_protobuf_FeatureSet_utf8_validation(f->resolved_features) == + google_protobuf_FeatureSet_VERIFY; +} + +bool _upb_FieldDef_IsGroupLike(const upb_FieldDef* f) { + // Groups are always tag-delimited. + if (f->type_ != kUpb_FieldType_Group) { + return false; + } + + const upb_MessageDef* msg = upb_FieldDef_MessageSubDef(f); + + // Group fields always are always the lowercase type name. + const char* mname = upb_MessageDef_Name(msg); + const char* fname = upb_FieldDef_Name(f); + size_t name_size = strlen(fname); + if (name_size != strlen(mname)) return false; + for (size_t i = 0; i < name_size; ++i) { + if ((mname[i] | 0x20) != fname[i]) { + // Case-insensitive ascii comparison. + return false; + } + } + + if (upb_MessageDef_File(msg) != upb_FieldDef_File(f)) { + return false; + } + + // Group messages are always defined in the same scope as the field. File + // level extensions will compare NULL == NULL here, which is why the file + // comparison above is necessary to ensure both come from the same file. + return upb_FieldDef_IsExtension(f) ? upb_FieldDef_ExtensionScope(f) == + upb_MessageDef_ContainingType(msg) + : upb_FieldDef_ContainingType(f) == + upb_MessageDef_ContainingType(msg); +} + +uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) { + uint64_t out = upb_FieldDef_IsPacked(f) ? kUpb_FieldModifier_IsPacked : 0; + + if (upb_FieldDef_IsRepeated(f)) { + out |= kUpb_FieldModifier_IsRepeated; + } else if (upb_FieldDef_IsRequired(f)) { + out |= kUpb_FieldModifier_IsRequired; + } else if (!upb_FieldDef_HasPresence(f)) { + out |= kUpb_FieldModifier_IsProto3Singular; + } + + if (_upb_FieldDef_IsClosedEnum(f)) { + out |= kUpb_FieldModifier_IsClosedEnum; + } + + if (_upb_FieldDef_ValidateUtf8(f)) { + out |= kUpb_FieldModifier_ValidateUtf8; + } + + return out; +} + +bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; } +bool upb_FieldDef_HasPresence(const upb_FieldDef* f) { return f->has_presence; } + +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) { + return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsEnum(f); +} + +bool upb_FieldDef_IsEnum(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Enum; +} + +bool upb_FieldDef_IsMap(const upb_FieldDef* f) { + return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsSubMessage(f) && + upb_MessageDef_IsMapEntry(upb_FieldDef_MessageSubDef(f)); +} + +bool upb_FieldDef_IsOptional(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Optional; +} + +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f) { + return !upb_FieldDef_IsString(f) && !upb_FieldDef_IsSubMessage(f); +} + +bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { + return upb_FieldDef_Label(f) == kUpb_Label_Repeated; +} + +bool upb_FieldDef_IsRequired(const upb_FieldDef* f) { + return google_protobuf_FeatureSet_field_presence(f->resolved_features) == + google_protobuf_FeatureSet_LEGACY_REQUIRED; +} + +bool upb_FieldDef_IsString(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_String || + upb_FieldDef_CType(f) == kUpb_CType_Bytes; +} + +bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) { + return upb_FieldDef_CType(f) == kUpb_CType_Message; +} + +static bool between(int32_t x, int32_t low, int32_t high) { + return x >= low && x <= high; +} + +bool upb_FieldDef_checklabel(int32_t label) { return between(label, 1, 3); } +bool upb_FieldDef_checktype(int32_t type) { return between(type, 1, 11); } +bool upb_FieldDef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); } + +bool upb_FieldDef_checkdescriptortype(int32_t type) { + return between(type, 1, 18); +} + +static bool streql2(const char* a, size_t n, const char* b) { + return n == strlen(b) && memcmp(a, b, n) == 0; +} + +// Implement the transformation as described in the spec: +// 1. upper case all letters after an underscore. +// 2. remove all underscores. +static char* make_json_name(const char* name, size_t size, upb_Arena* a) { + char* out = upb_Arena_Malloc(a, size + 1); // +1 is to add a trailing '\0' + if (out == NULL) return NULL; + + bool ucase_next = false; + char* des = out; + for (size_t i = 0; i < size; i++) { + if (name[i] == '_') { + ucase_next = true; + } else { + *des++ = ucase_next ? toupper(name[i]) : name[i]; + ucase_next = false; + } + } + *des++ = '\0'; + return out; +} + +static str_t* newstr(upb_DefBuilder* ctx, const char* data, size_t len) { + str_t* ret = _upb_DefBuilder_Alloc(ctx, sizeof(*ret) + len); + if (!ret) _upb_DefBuilder_OomErr(ctx); + ret->len = len; + if (len) memcpy(ret->str, data, len); + ret->str[len] = '\0'; + return ret; +} + +static str_t* unescape(upb_DefBuilder* ctx, const upb_FieldDef* f, + const char* data, size_t len) { + // Size here is an upper bound; escape sequences could ultimately shrink it. + str_t* ret = _upb_DefBuilder_Alloc(ctx, sizeof(*ret) + len); + char* dst = &ret->str[0]; + const char* src = data; + const char* end = data + len; + + while (src < end) { + if (*src == '\\') { + src++; + *dst++ = _upb_DefBuilder_ParseEscape(ctx, f, &src, end); + } else { + *dst++ = *src++; + } + } + + ret->len = dst - &ret->str[0]; + return ret; +} + +static void parse_default(upb_DefBuilder* ctx, const char* str, size_t len, + upb_FieldDef* f) { + char* end; + char nullz[64]; + errno = 0; + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + case kUpb_CType_UInt32: + case kUpb_CType_UInt64: + case kUpb_CType_Double: + case kUpb_CType_Float: + // Standard C number parsing functions expect null-terminated strings. + if (len >= sizeof(nullz) - 1) { + _upb_DefBuilder_Errf(ctx, "Default too long: %.*s", (int)len, str); + } + memcpy(nullz, str, len); + nullz[len] = '\0'; + str = nullz; + break; + default: + break; + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: { + long val = strtol(str, &end, 0); + if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case kUpb_CType_Enum: { + const upb_EnumDef* e = f->sub.enumdef; + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNameWithSize(e, str, len); + if (!ev) { + goto invalid; + } + f->defaultval.sint = upb_EnumValueDef_Number(ev); + break; + } + case kUpb_CType_Int64: { + long long val = strtoll(str, &end, 0); + if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.sint = val; + break; + } + case kUpb_CType_UInt32: { + unsigned long val = strtoul(str, &end, 0); + if (val > UINT32_MAX || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.uint = val; + break; + } + case kUpb_CType_UInt64: { + unsigned long long val = strtoull(str, &end, 0); + if (val > UINT64_MAX || errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.uint = val; + break; + } + case kUpb_CType_Double: { + double val = strtod(str, &end); + if (errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.dbl = val; + break; + } + case kUpb_CType_Float: { + float val = strtof(str, &end); + if (errno == ERANGE || *end) { + goto invalid; + } + f->defaultval.flt = val; + break; + } + case kUpb_CType_Bool: { + if (streql2(str, len, "false")) { + f->defaultval.boolean = false; + } else if (streql2(str, len, "true")) { + f->defaultval.boolean = true; + } else { + goto invalid; + } + break; + } + case kUpb_CType_String: + f->defaultval.str = newstr(ctx, str, len); + break; + case kUpb_CType_Bytes: + f->defaultval.str = unescape(ctx, f, str, len); + break; + case kUpb_CType_Message: + /* Should not have a default value. */ + _upb_DefBuilder_Errf(ctx, "Message should not have a default (%s)", + upb_FieldDef_FullName(f)); + } + + return; + +invalid: + _upb_DefBuilder_Errf(ctx, "Invalid default '%.*s' for field %s of type %d", + (int)len, str, upb_FieldDef_FullName(f), + (int)upb_FieldDef_Type(f)); +} + +static void set_default_default(upb_DefBuilder* ctx, upb_FieldDef* f, + bool must_be_empty) { + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Int32: + case kUpb_CType_Int64: + f->defaultval.sint = 0; + break; + case kUpb_CType_UInt64: + case kUpb_CType_UInt32: + f->defaultval.uint = 0; + break; + case kUpb_CType_Double: + case kUpb_CType_Float: + f->defaultval.dbl = 0; + break; + case kUpb_CType_String: + case kUpb_CType_Bytes: + f->defaultval.str = newstr(ctx, NULL, 0); + break; + case kUpb_CType_Bool: + f->defaultval.boolean = false; + break; + case kUpb_CType_Enum: { + f->defaultval.sint = upb_EnumDef_Default(f->sub.enumdef); + if (must_be_empty && f->defaultval.sint != 0) { + _upb_DefBuilder_Errf(ctx, + "Implicit presence field (%s) cannot use an enum " + "type with a non-zero default (%s)", + f->full_name, + upb_EnumDef_FullName(f->sub.enumdef)); + } + break; + } + case kUpb_CType_Message: + break; + } +} + +static bool _upb_FieldDef_InferLegacyFeatures( + upb_DefBuilder* ctx, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* proto, + const google_protobuf_FieldOptions* options, google_protobuf_Edition edition, + google_protobuf_FeatureSet* features) { + bool ret = false; + + if (google_protobuf_FieldDescriptorProto_label(proto) == kUpb_Label_Required) { + if (edition == google_protobuf_EDITION_PROTO3) { + _upb_DefBuilder_Errf(ctx, "proto3 fields cannot be required (%s)", + f->full_name); + } + int val = google_protobuf_FeatureSet_LEGACY_REQUIRED; + google_protobuf_FeatureSet_set_field_presence(features, val); + ret = true; + } + + if (google_protobuf_FieldDescriptorProto_type(proto) == kUpb_FieldType_Group) { + int val = google_protobuf_FeatureSet_DELIMITED; + google_protobuf_FeatureSet_set_message_encoding(features, val); + ret = true; + } + + if (google_protobuf_FieldOptions_has_packed(options)) { + int val = google_protobuf_FieldOptions_packed(options) ? google_protobuf_FeatureSet_PACKED + : google_protobuf_FeatureSet_EXPANDED; + google_protobuf_FeatureSet_set_repeated_field_encoding(features, val); + ret = true; + } + + return ret; +} + +static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_FeatureSet* parent_features, + const google_protobuf_FieldDescriptorProto* field_proto, + upb_MessageDef* m, upb_FieldDef* f) { + // Must happen before _upb_DefBuilder_Add() + f->file = _upb_DefBuilder_File(ctx); + + const upb_StringView name = google_protobuf_FieldDescriptorProto_name(field_proto); + f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + f->number_ = google_protobuf_FieldDescriptorProto_number(field_proto); + f->is_proto3_optional = + google_protobuf_FieldDescriptorProto_proto3_optional(field_proto); + f->msgdef = m; + f->scope.oneof = NULL; + + UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); + + google_protobuf_Edition edition = upb_FileDef_Edition(f->file); + const google_protobuf_FeatureSet* unresolved_features = + google_protobuf_FieldOptions_features(f->opts); + bool implicit = false; + + if (_upb_DefBuilder_IsLegacyEdition(edition)) { + upb_Message_Clear(UPB_UPCAST(ctx->legacy_features), + UPB_DESC_MINITABLE(FeatureSet)); + if (_upb_FieldDef_InferLegacyFeatures(ctx, f, field_proto, f->opts, edition, + ctx->legacy_features)) { + implicit = true; + unresolved_features = ctx->legacy_features; + } + } + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto); + + if (!m) { + _upb_DefBuilder_Errf(ctx, "oneof field (%s) has no containing msg", + f->full_name); + } + + if (oneof_index < 0 || oneof_index >= upb_MessageDef_OneofCount(m)) { + _upb_DefBuilder_Errf(ctx, "oneof_index out of range (%s)", f->full_name); + } + + upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index); + f->scope.oneof = oneof; + parent_features = upb_OneofDef_ResolvedFeatures(oneof); + + _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size); + } + + f->resolved_features = _upb_DefBuilder_DoResolveFeatures( + ctx, parent_features, unresolved_features, implicit); + + f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto); + if (f->label_ == kUpb_Label_Optional && + // TODO: remove once we can deprecate kUpb_Label_Required. + google_protobuf_FeatureSet_field_presence(f->resolved_features) == + google_protobuf_FeatureSet_LEGACY_REQUIRED) { + f->label_ = kUpb_Label_Required; + } + + if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) { + _upb_DefBuilder_Errf(ctx, "field has no name"); + } + + f->has_json_name = google_protobuf_FieldDescriptorProto_has_json_name(field_proto); + if (f->has_json_name) { + const upb_StringView sv = + google_protobuf_FieldDescriptorProto_json_name(field_proto); + f->json_name = upb_strdup2(sv.data, sv.size, ctx->arena); + } else { + f->json_name = make_json_name(name.data, name.size, ctx->arena); + } + if (!f->json_name) _upb_DefBuilder_OomErr(ctx); + + const bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto); + const bool has_type_name = + google_protobuf_FieldDescriptorProto_has_type_name(field_proto); + + f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto); + + if (has_type) { + switch (f->type_) { + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + case kUpb_FieldType_Enum: + if (!has_type_name) { + _upb_DefBuilder_Errf(ctx, "field of type %d requires type name (%s)", + (int)f->type_, f->full_name); + } + break; + default: + if (has_type_name) { + _upb_DefBuilder_Errf( + ctx, "invalid type for field with type_name set (%s, %d)", + f->full_name, (int)f->type_); + } + } + } + + if ((!has_type && has_type_name) || f->type_ == kUpb_FieldType_Message) { + f->type_ = + UPB_FIELD_TYPE_UNSPECIFIED; // We'll assign this in resolve_subdef() + } else { + if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) { + _upb_DefBuilder_Errf(ctx, "invalid type for field %s (%d)", f->full_name, + f->type_); + } + } + + if (f->label_ < kUpb_Label_Optional || f->label_ > kUpb_Label_Repeated) { + _upb_DefBuilder_Errf(ctx, "invalid label for field %s (%d)", f->full_name, + f->label_); + } + + /* We can't resolve the subdef or (in the case of extensions) the containing + * message yet, because it may not have been defined yet. We stash a pointer + * to the field_proto until later when we can properly resolve it. */ + f->sub.unresolved = field_proto; + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + if (upb_FieldDef_Label(f) != kUpb_Label_Optional) { + _upb_DefBuilder_Errf(ctx, "fields in oneof must have OPTIONAL label (%s)", + f->full_name); + } + } + + f->has_presence = + (!upb_FieldDef_IsRepeated(f)) && + (f->is_extension || _upb_FileDef_ImplicitFieldPresenceDisabled(f->file) || + (f->type_ == kUpb_FieldType_Message || + f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) || + google_protobuf_FeatureSet_field_presence(f->resolved_features) != + google_protobuf_FeatureSet_IMPLICIT)); +} + +static void _upb_FieldDef_CreateExt( + upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_FeatureSet* parent_features, + const google_protobuf_FieldDescriptorProto* field_proto, upb_MessageDef* m, + upb_FieldDef* f) { + f->is_extension = true; + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); + + if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + _upb_DefBuilder_Errf(ctx, "oneof_index provided for extension field (%s)", + f->full_name); + } + + f->scope.extension_scope = m; + _upb_DefBuilder_Add(ctx, f->full_name, _upb_DefType_Pack(f, UPB_DEFTYPE_EXT)); + f->layout_index = ctx->ext_count++; + + if (ctx->layout) { + UPB_ASSERT(upb_MiniTableExtension_Number( + upb_FieldDef_MiniTableExtension(f)) == f->number_); + } +} + +static void _upb_FieldDef_CreateNotExt( + upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_FeatureSet* parent_features, + const google_protobuf_FieldDescriptorProto* field_proto, upb_MessageDef* m, + upb_FieldDef* f) { + f->is_extension = false; + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); + + if (!google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) { + if (f->is_proto3_optional) { + _upb_DefBuilder_Errf( + ctx, + "non-extension field (%s) with proto3_optional was not in a oneof", + f->full_name); + } + } + + _upb_MessageDef_InsertField(ctx, m, f); +} + +upb_FieldDef* _upb_Extensions_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m) { + _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); + upb_FieldDef* defs = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_FieldDef, n); + + for (int i = 0; i < n; i++) { + upb_FieldDef* f = &defs[i]; + + _upb_FieldDef_CreateExt(ctx, prefix, parent_features, protos[i], m, f); + f->index_ = i; + } + + return defs; +} + +upb_FieldDef* _upb_FieldDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m, bool* is_sorted) { + _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); + upb_FieldDef* defs = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_FieldDef, n); + + uint32_t previous = 0; + for (int i = 0; i < n; i++) { + upb_FieldDef* f = &defs[i]; + + _upb_FieldDef_CreateNotExt(ctx, prefix, parent_features, protos[i], m, f); + f->index_ = i; + if (!ctx->layout) { + // Speculate that the def fields are sorted. We will always sort the + // MiniTable fields, so if defs are sorted then indices will match. + // + // If this is incorrect, we will overwrite later. + f->layout_index = i; + } + + const uint32_t current = f->number_; + if (previous > current) *is_sorted = false; + previous = current; + } + + return defs; +} + +static void resolve_subdef(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f) { + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + upb_StringView name = google_protobuf_FieldDescriptorProto_type_name(field_proto); + bool has_name = google_protobuf_FieldDescriptorProto_has_type_name(field_proto); + switch ((int)f->type_) { + case UPB_FIELD_TYPE_UNSPECIFIED: { + // Type was not specified and must be inferred. + UPB_ASSERT(has_name); + upb_deftype_t type; + const void* def = + _upb_DefBuilder_ResolveAny(ctx, f->full_name, prefix, name, &type); + switch (type) { + case UPB_DEFTYPE_ENUM: + f->sub.enumdef = def; + f->type_ = kUpb_FieldType_Enum; + break; + case UPB_DEFTYPE_MSG: + f->sub.msgdef = def; + f->type_ = kUpb_FieldType_Message; + // TODO: remove once we can deprecate + // kUpb_FieldType_Group. + if (google_protobuf_FeatureSet_message_encoding(f->resolved_features) == + google_protobuf_FeatureSet_DELIMITED && + !upb_MessageDef_IsMapEntry(def) && + !(f->msgdef && upb_MessageDef_IsMapEntry(f->msgdef))) { + f->type_ = kUpb_FieldType_Group; + } + f->has_presence = !upb_FieldDef_IsRepeated(f); + break; + default: + _upb_DefBuilder_Errf(ctx, "Couldn't resolve type name for field %s", + f->full_name); + } + break; + } + case kUpb_FieldType_Message: + case kUpb_FieldType_Group: + UPB_ASSERT(has_name); + f->sub.msgdef = _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, + UPB_DEFTYPE_MSG); + break; + case kUpb_FieldType_Enum: + UPB_ASSERT(has_name); + f->sub.enumdef = _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, + UPB_DEFTYPE_ENUM); + break; + default: + // No resolution necessary. + break; + } +} + +static int _upb_FieldDef_Compare(const void* p1, const void* p2) { + const uint32_t v1 = (*(upb_FieldDef**)p1)->number_; + const uint32_t v2 = (*(upb_FieldDef**)p2)->number_; + return (v1 < v2) ? -1 : (v1 > v2); +} + +// _upb_FieldDefs_Sorted() is mostly a pure function of its inputs, but has one +// critical side effect that we depend on: it sets layout_index appropriately +// for non-sorted lists of fields. +const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n, + upb_Arena* a) { + // TODO: Replace this arena alloc with a persistent scratch buffer. + upb_FieldDef** out = (upb_FieldDef**)upb_Arena_Malloc(a, n * sizeof(void*)); + if (!out) return NULL; + + for (int i = 0; i < n; i++) { + out[i] = (upb_FieldDef*)&f[i]; + } + qsort(out, n, sizeof(void*), _upb_FieldDef_Compare); + + for (int i = 0; i < n; i++) { + out[i]->layout_index = i; + } + 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); + + 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_EncodeExtension(&s.e, s.ptr, f->type_, number, + modifiers); + *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) { + if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) { + _upb_DefBuilder_Errf(ctx, "extension for field '%s' had no extendee", + f->full_name); + } + + upb_StringView name = google_protobuf_FieldDescriptorProto_extendee(field_proto); + const upb_MessageDef* m = + _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG); + f->msgdef = m; + + if (!_upb_MessageDef_IsValidExtensionNumber(m, f->number_)) { + _upb_DefBuilder_Errf( + ctx, + "field number %u in extension %s has no extension range in message %s", + (unsigned)f->number_, f->full_name, upb_MessageDef_FullName(m)); + } +} + +void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, + const upb_FieldDef* f) { + const upb_MiniTableExtension* ext = upb_FieldDef_MiniTableExtension(f); + + if (ctx->layout) { + UPB_ASSERT(upb_FieldDef_Number(f) == upb_MiniTableExtension_Number(ext)); + } else { + upb_StringView desc; + if (!upb_FieldDef_MiniDescriptorEncode(f, ctx->tmp_arena, &desc)) { + _upb_DefBuilder_OomErr(ctx); + } + + upb_MiniTableExtension* mut_ext = (upb_MiniTableExtension*)ext; + upb_MiniTableSub sub = {NULL}; + if (upb_FieldDef_IsSubMessage(f)) { + const upb_MiniTable* submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + sub = upb_MiniTableSub_FromMessage(submsg); + } else if (_upb_FieldDef_IsClosedEnum(f)) { + const upb_MiniTableEnum* subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + sub = upb_MiniTableSub_FromEnum(subenum); + } + bool ok2 = _upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext, + upb_MessageDef_MiniTable(f->msgdef), + sub, ctx->platform, ctx->status); + if (!ok2) _upb_DefBuilder_Errf(ctx, "Could not build extension mini table"); + } + + bool ok = _upb_DefPool_InsertExt(ctx->symtab, ext, f); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +static void resolve_default(upb_DefBuilder* ctx, upb_FieldDef* f, + const google_protobuf_FieldDescriptorProto* field_proto) { + // Implicit presence fields should always have an effective default of 0. + // This should naturally fall out of the validations that protoc performs: + // - Implicit presence fields cannot specify a default value. + // - Implicit presence fields for for enums can only use open enums, which + // are required to have zero as their default. + // - Even if we are treating all enums as open, the proto compiler will + // still reject using a nominally closed enum with an implicit presence + // field. + bool must_be_empty = !f->has_presence && !upb_FieldDef_IsRepeated(f); + + // Have to delay resolving of the default value until now because of the enum + // case, since enum defaults are specified with a label. + if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) { + upb_StringView defaultval = + google_protobuf_FieldDescriptorProto_default_value(field_proto); + + if (must_be_empty) { + _upb_DefBuilder_Errf(ctx, + "fields with implicit presence cannot have " + "explicit defaults (%s)", + f->full_name); + } + + if (upb_FileDef_Edition(f->file) == google_protobuf_EDITION_PROTO3) { + _upb_DefBuilder_Errf(ctx, + "proto3 fields cannot have explicit defaults (%s)", + f->full_name); + } + + if (upb_FieldDef_IsSubMessage(f)) { + _upb_DefBuilder_Errf(ctx, + "message fields cannot have explicit defaults (%s)", + f->full_name); + } + + parse_default(ctx, defaultval.data, defaultval.size, f); + f->has_default = true; + } else { + set_default_default(ctx, f, must_be_empty); + f->has_default = false; + } +} + +void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f) { + // We have to stash this away since resolve_subdef() may overwrite it. + const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved; + + resolve_subdef(ctx, prefix, f); + resolve_default(ctx, f, field_proto); + + if (f->is_extension) { + resolve_extension(ctx, prefix, f, field_proto); + } +} + + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +struct upb_FileDef { + const google_protobuf_FileOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const char* name; + const char* package; + google_protobuf_Edition edition; + + const upb_FileDef** deps; + const int32_t* public_deps; + const int32_t* weak_deps; + const upb_MessageDef* top_lvl_msgs; + const upb_EnumDef* top_lvl_enums; + const upb_FieldDef* top_lvl_exts; + const upb_ServiceDef* services; + const upb_MiniTableExtension** ext_layouts; + const upb_DefPool* symtab; + + int dep_count; + int public_dep_count; + int weak_dep_count; + int top_lvl_msg_count; + int top_lvl_enum_count; + int top_lvl_ext_count; + int service_count; + int ext_count; // All exts in the file. +}; + +UPB_API const char* upb_FileDef_EditionName(int edition) { + // TODO Synchronize this with descriptor.proto better. + switch (edition) { + case google_protobuf_EDITION_PROTO2: + return "PROTO2"; + case google_protobuf_EDITION_PROTO3: + return "PROTO3"; + case google_protobuf_EDITION_2023: + return "2023"; + default: + return "UNKNOWN"; + } +} + +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { + return f->opts; +} + +const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f) { + return f->resolved_features; +} + +bool upb_FileDef_HasOptions(const upb_FileDef* f) { + return f->opts != (void*)kUpbDefOptDefault; +} + +const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; } + +const char* upb_FileDef_Package(const upb_FileDef* f) { + return f->package ? f->package : ""; +} + +google_protobuf_Edition upb_FileDef_Edition(const upb_FileDef* f) { return f->edition; } + +const char* _upb_FileDef_RawPackage(const upb_FileDef* f) { return f->package; } + +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) { + return f->top_lvl_msg_count; +} + +int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; } + +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { + return f->public_dep_count; +} + +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { + return f->weak_dep_count; +} + +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { + return f->public_deps; +} + +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { + return f->weak_deps; +} + +bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f) { + return upb_DefPool_ClosedEnumCheckingDisabled(f->symtab); +} + +bool _upb_FileDef_ImplicitFieldPresenceDisabled(const upb_FileDef* f) { + return upb_DefPool_ImplicitFieldPresenceDisabled(f->symtab); +} + +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { + return f->top_lvl_enum_count; +} + +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) { + return f->top_lvl_ext_count; +} + +int upb_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; } + +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->dep_count); + return f->deps[i]; +} + +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->public_deps[i]]; +} + +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->public_dep_count); + return f->deps[f->weak_deps[i]]; +} + +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count); + return _upb_MessageDef_At(f->top_lvl_msgs, i); +} + +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count); + return _upb_EnumDef_At(f->top_lvl_enums, i); +} + +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count); + return _upb_FieldDef_At(f->top_lvl_exts, i); +} + +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->service_count); + return _upb_ServiceDef_At(f->services, i); +} + +const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; } + +const upb_MiniTableExtension* _upb_FileDef_ExtensionMiniTable( + const upb_FileDef* f, int i) { + return f->ext_layouts[i]; +} + +// Note: Import cycles are not allowed so this will terminate. +bool upb_FileDef_Resolves(const upb_FileDef* f, const char* path) { + if (!strcmp(f->name, path)) return true; + + for (int i = 0; i < upb_FileDef_PublicDependencyCount(f); i++) { + const upb_FileDef* dep = upb_FileDef_PublicDependency(f, i); + if (upb_FileDef_Resolves(dep, path)) return true; + } + return false; +} + +static char* _strviewdup(upb_DefBuilder* ctx, upb_StringView view) { + char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx)); + if (!ret) _upb_DefBuilder_OomErr(ctx); + return ret; +} + +static bool streql_view(upb_StringView view, const char* b) { + return view.size == strlen(b) && memcmp(view.data, b, view.size) == 0; +} + +static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) { + size_t n; + google_protobuf_DescriptorProto_extension(msg_proto, &n); + int ext_count = n; + + const google_protobuf_DescriptorProto* const* nested_msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n); + for (size_t i = 0; i < n; i++) { + ext_count += count_exts_in_msg(nested_msgs[i]); + } + + return ext_count; +} + +const google_protobuf_FeatureSet* _upb_FileDef_FindEdition(upb_DefBuilder* ctx, + int edition) { + const google_protobuf_FeatureSetDefaults* defaults = + upb_DefPool_FeatureSetDefaults(ctx->symtab); + + int min = google_protobuf_FeatureSetDefaults_minimum_edition(defaults); + int max = google_protobuf_FeatureSetDefaults_maximum_edition(defaults); + if (edition < min) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is earlier than the minimum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(min)); + return NULL; + } + if (edition > max && edition != google_protobuf_EDITION_UNSTABLE) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is later than the maximum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(max)); + return NULL; + } + + size_t n; + const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* d = + google_protobuf_FeatureSetDefaults_defaults(defaults, &n); + const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* result = NULL; + for (size_t i = 0; i < n; i++) { + if (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition(d[i]) > + edition) { + break; + } + result = d[i]; + } + if (result == NULL) { + _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s", + upb_FileDef_EditionName(edition)); + return NULL; + } + + // Merge the fixed and overridable features to get the edition's default + // feature set. + const google_protobuf_FeatureSet* fixed = + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_fixed_features(result); + const google_protobuf_FeatureSet* overridable = + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_overridable_features( + result); + if (!fixed && !overridable) { + _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s", + upb_FileDef_EditionName(edition)); + return NULL; + } else if (!fixed) { + return overridable; + } + return _upb_DefBuilder_DoResolveFeatures(ctx, fixed, overridable, + /*is_implicit=*/true); +} + +// Allocate and initialize one file def, and add it to the context object. +void _upb_FileDef_Create(upb_DefBuilder* ctx, + const google_protobuf_FileDescriptorProto* file_proto) { + upb_FileDef* file = _upb_DefBuilder_Alloc(ctx, sizeof(upb_FileDef)); + ctx->file = file; + + const google_protobuf_DescriptorProto* const* msgs; + const google_protobuf_EnumDescriptorProto* const* enums; + const google_protobuf_FieldDescriptorProto* const* exts; + const google_protobuf_ServiceDescriptorProto* const* services; + const upb_StringView* strs; + const int32_t* public_deps; + const int32_t* weak_deps; + size_t n; + + file->symtab = ctx->symtab; + + // Count all extensions in the file, to build a flat array of layouts. + google_protobuf_FileDescriptorProto_extension(file_proto, &n); + int ext_count = n; + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + for (size_t i = 0; i < n; i++) { + ext_count += count_exts_in_msg(msgs[i]); + } + file->ext_count = ext_count; + + if (ctx->layout) { + // We are using the ext layouts that were passed in. + file->ext_layouts = ctx->layout->UPB_PRIVATE(exts); + const int mt_ext_count = upb_MiniTableFile_ExtensionCount(ctx->layout); + if (mt_ext_count != file->ext_count) { + _upb_DefBuilder_Errf(ctx, + "Extension count did not match layout (%d vs %d)", + mt_ext_count, file->ext_count); + } + } else { + // We are building ext layouts from scratch. + file->ext_layouts = _upb_DefBuilder_Alloc( + ctx, sizeof(*file->ext_layouts) * file->ext_count); + upb_MiniTableExtension* ext = + UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MiniTableExtension, file->ext_count); + for (int i = 0; i < file->ext_count; i++) { + file->ext_layouts[i] = &ext[i]; + } + } + + upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); + file->name = _strviewdup(ctx, name); + if (strlen(file->name) != name.size) { + _upb_DefBuilder_Errf(ctx, "File name contained embedded NULL"); + } + + upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto); + + if (package.size) { + _upb_DefBuilder_CheckIdentFull(ctx, package); + file->package = _strviewdup(ctx, package); + } else { + file->package = NULL; + } + + upb_StringView syntax = google_protobuf_FileDescriptorProto_syntax(file_proto); + + if (google_protobuf_FileDescriptorProto_has_edition(file_proto)) { + if (!streql_view(syntax, "editions")) { + _upb_DefBuilder_Errf(ctx, + "Setting edition requires that syntax=\"editions\", " + "but syntax is \"" UPB_STRINGVIEW_FORMAT "\"", + UPB_STRINGVIEW_ARGS(syntax)); + } + file->edition = google_protobuf_FileDescriptorProto_edition(file_proto); + } else if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { + if (streql_view(syntax, "proto2")) { + file->edition = google_protobuf_EDITION_PROTO2; + } else if (streql_view(syntax, "proto3")) { + file->edition = google_protobuf_EDITION_PROTO3; + } else if (streql_view(syntax, "editions")) { + _upb_DefBuilder_Errf( + ctx, "File has syntax=\"editions\", but no edition is specified"); + } else { + _upb_DefBuilder_Errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(syntax)); + } + } else { + // The legacy default when no edition or syntax is specified is proto2. + file->edition = google_protobuf_EDITION_PROTO2; + } + + // Read options. + UPB_DEF_SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); + + // Resolve features. + const google_protobuf_FeatureSet* edition_defaults = + _upb_FileDef_FindEdition(ctx, file->edition); + const google_protobuf_FeatureSet* unresolved = google_protobuf_FileOptions_features(file->opts); + file->resolved_features = + _upb_DefBuilder_ResolveFeatures(ctx, edition_defaults, unresolved); + + // Verify dependencies. + strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); + file->dep_count = n; + file->deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const upb_FileDef*, n); + + for (size_t i = 0; i < n; i++) { + upb_StringView str = strs[i]; + file->deps[i] = + upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size); + if (!file->deps[i]) { + _upb_DefBuilder_Errf(ctx, + "Depends on file '" UPB_STRINGVIEW_FORMAT + "', but it has not been loaded", + UPB_STRINGVIEW_ARGS(str)); + } + } + + public_deps = google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n); + file->public_dep_count = n; + file->public_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, int32_t, n); + int32_t* mutable_public_deps = (int32_t*)file->public_deps; + for (size_t i = 0; i < n; i++) { + if (public_deps[i] >= file->dep_count) { + _upb_DefBuilder_Errf(ctx, "public_dep %d is out of range", + (int)public_deps[i]); + } + mutable_public_deps[i] = public_deps[i]; + } + + weak_deps = google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n); + file->weak_dep_count = n; + file->weak_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const int32_t, n); + int32_t* mutable_weak_deps = (int32_t*)file->weak_deps; + for (size_t i = 0; i < n; i++) { + if (weak_deps[i] >= file->dep_count) { + _upb_DefBuilder_Errf(ctx, "weak_dep %d is out of range", + (int)weak_deps[i]); + } + mutable_weak_deps[i] = weak_deps[i]; + } + + // Create enums. + enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); + file->top_lvl_enum_count = n; + file->top_lvl_enums = + _upb_EnumDefs_New(ctx, n, enums, file->resolved_features, NULL); + + // Create extensions. + exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); + file->top_lvl_ext_count = n; + file->top_lvl_exts = _upb_Extensions_New( + ctx, n, exts, file->resolved_features, file->package, NULL); + + // Create messages. + msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); + file->top_lvl_msg_count = n; + file->top_lvl_msgs = + _upb_MessageDefs_New(ctx, n, msgs, file->resolved_features, NULL); + + // Create services. + services = google_protobuf_FileDescriptorProto_service(file_proto, &n); + file->service_count = n; + file->services = + _upb_ServiceDefs_New(ctx, n, services, file->resolved_features); + + // Now that all names are in the table, build layouts and resolve refs. + + for (int i = 0; i < file->top_lvl_msg_count; i++) { + upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); + _upb_MessageDef_Resolve(ctx, m); + } + + for (int i = 0; i < file->top_lvl_ext_count; i++) { + upb_FieldDef* f = (upb_FieldDef*)upb_FileDef_TopLevelExtension(file, i); + _upb_FieldDef_Resolve(ctx, file->package, f); + } + + for (int i = 0; i < file->top_lvl_msg_count; i++) { + upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); + _upb_MessageDef_CreateMiniTable(ctx, (upb_MessageDef*)m); + } + + for (int i = 0; i < file->top_lvl_ext_count; i++) { + upb_FieldDef* f = (upb_FieldDef*)upb_FileDef_TopLevelExtension(file, i); + _upb_FieldDef_BuildMiniTableExtension(ctx, f); + } + + for (int i = 0; i < file->top_lvl_msg_count; i++) { + upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); + _upb_MessageDef_LinkMiniTable(ctx, m); + } + + if (file->ext_count) { + upb_ExtensionRegistryStatus status = upb_ExtensionRegistry_AddArray( + _upb_DefPool_ExtReg(ctx->symtab), file->ext_layouts, file->ext_count); + if (status != kUpb_ExtensionRegistryStatus_Ok) { + if (status == kUpb_ExtensionRegistryStatus_OutOfMemory) { + _upb_DefBuilder_OomErr(ctx); + } + + UPB_ASSERT(status == kUpb_ExtensionRegistryStatus_DuplicateEntry); + _upb_DefBuilder_Errf(ctx, "duplicate extension entry"); + } + } +} + + +#include <assert.h> +#include <stdarg.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +/* The upb core does not generally have a concept of default instances. However + * for descriptor options we make an exception since the max size is known and + * modest (<200 bytes). All types can share a default instance since it is + * initialized to zeroes. + * + * We have to allocate an extra pointer for upb's internal metadata. */ +static UPB_ALIGN_AS(8) const + char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0}; +const char* kUpbDefOptDefault = &opt_default_buf[sizeof(void*)]; + +const char* _upb_DefBuilder_FullToShort(const char* fullname) { + const char* p; + + if (fullname == NULL) { + return NULL; + } else if ((p = strrchr(fullname, '.')) == NULL) { + /* No '.' in the name, return the full string. */ + return fullname; + } else { + /* Return one past the last '.'. */ + return p + 1; + } +} + +void _upb_DefBuilder_FailJmp(upb_DefBuilder* ctx) { UPB_LONGJMP(ctx->err, 1); } + +void _upb_DefBuilder_Errf(upb_DefBuilder* ctx, const char* fmt, ...) { + va_list argp; + va_start(argp, fmt); + upb_Status_VSetErrorFormat(ctx->status, fmt, argp); + va_end(argp); + _upb_DefBuilder_FailJmp(ctx); +} + +void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx) { + upb_Status_SetErrorMessage(ctx->status, "out of memory"); + _upb_DefBuilder_FailJmp(ctx); +} + +// Verify a relative identifier string. The loop is branchless for speed. +static void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx, + upb_StringView name) { + bool good = name.size > 0; + + for (size_t i = 0; i < name.size; i++) { + const char c = name.data[i]; + const char d = c | 0x20; // force lowercase + const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); + const bool is_numer = ('0' <= c) & (c <= '9') & (i != 0); + + good &= is_alpha | is_numer; + } + + if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false); +} + +const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx, + const char* prefix, + upb_StringView name) { + _upb_DefBuilder_CheckIdentNotFull(ctx, name); + if (prefix) { + // ret = prefix + '.' + name; + size_t n = strlen(prefix); + char* ret = _upb_DefBuilder_Alloc(ctx, n + name.size + 2); + strcpy(ret, prefix); + ret[n] = '.'; + memcpy(&ret[n + 1], name.data, name.size); + ret[n + 1 + name.size] = '\0'; + return ret; + } else { + char* ret = upb_strdup2(name.data, name.size, ctx->arena); + if (!ret) _upb_DefBuilder_OomErr(ctx); + return ret; + } +} + +static bool remove_component(char* base, size_t* len) { + if (*len == 0) return false; + + for (size_t i = *len - 1; i > 0; i--) { + if (base[i] == '.') { + *len = i; + return true; + } + } + + *len = 0; + return true; +} + +const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, + const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t* type) { + if (sym.size == 0) goto notfound; + upb_value v; + if (sym.data[0] == '.') { + // Symbols starting with '.' are absolute, so we do a single lookup. + // Slice to omit the leading '.' + if (!_upb_DefPool_LookupSym(ctx->symtab, sym.data + 1, sym.size - 1, &v)) { + goto notfound; + } + } else { + // Remove components from base until we find an entry or run out. + size_t baselen = base ? strlen(base) : 0; + char* tmp = upb_gmalloc(sym.size + baselen + 1); + while (1) { + char* p = tmp; + if (baselen) { + memcpy(p, base, baselen); + p[baselen] = '.'; + p += baselen + 1; + } + memcpy(p, sym.data, sym.size); + p += sym.size; + if (_upb_DefPool_LookupSym(ctx->symtab, tmp, p - tmp, &v)) { + break; + } + if (!remove_component(tmp, &baselen)) { + upb_gfree(tmp); + goto notfound; + } + } + upb_gfree(tmp); + } + + *type = _upb_DefType_Type(v); + return _upb_DefType_Unpack(v, *type); + +notfound: + _upb_DefBuilder_Errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'", + UPB_STRINGVIEW_ARGS(sym)); +} + +const void* _upb_DefBuilder_Resolve(upb_DefBuilder* ctx, + const char* from_name_dbg, const char* base, + upb_StringView sym, upb_deftype_t type) { + upb_deftype_t found_type; + const void* ret = + _upb_DefBuilder_ResolveAny(ctx, from_name_dbg, base, sym, &found_type); + if (ret && found_type != type) { + _upb_DefBuilder_Errf(ctx, + "type mismatch when resolving %s: couldn't find " + "name " UPB_STRINGVIEW_FORMAT " with type=%d", + from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (int)type); + } + return ret; +} + +// Per ASCII this will lower-case a letter. If the result is a letter, the +// input was definitely a letter. If the output is not a letter, this may +// have transformed the character unpredictably. +static char upb_ascii_lower(char ch) { return ch | 0x20; } + +// isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. +static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) { + return low <= c && c <= high; +} + +static bool upb_isletter(char c) { + char lower = upb_ascii_lower(c); + return upb_isbetween(lower, 'a', 'z') || c == '_'; +} + +static bool upb_isalphanum(char c) { + return upb_isletter(c) || upb_isbetween(c, '0', '9'); +} + +static bool TryGetChar(const char** src, const char* end, char* ch) { + if (*src == end) return false; + *ch = **src; + *src += 1; + return true; +} + +static int TryGetHexDigit(const char** src, const char* end) { + char ch; + if (!TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '9') { + return ch - '0'; + } + ch = upb_ascii_lower(ch); + if ('a' <= ch && ch <= 'f') { + return ch - 'a' + 0xa; + } + *src -= 1; // Char wasn't actually a hex digit. + return -1; +} + +static char upb_DefBuilder_ParseHexEscape(upb_DefBuilder* ctx, + const upb_FieldDef* f, + const char** src, const char* end) { + int hex_digit = TryGetHexDigit(src, end); + if (hex_digit < 0) { + _upb_DefBuilder_Errf( + ctx, "\\x must be followed by at least one hex digit (field='%s')", + upb_FieldDef_FullName(f)); + return 0; + } + unsigned int ret = hex_digit; + while ((hex_digit = TryGetHexDigit(src, end)) >= 0) { + ret = (ret << 4) | hex_digit; + } + if (ret > 0xff) { + _upb_DefBuilder_Errf(ctx, "Value of hex escape in field %s exceeds 8 bits", + upb_FieldDef_FullName(f)); + return 0; + } + return ret; +} + +static char TryGetOctalDigit(const char** src, const char* end) { + char ch; + if (!TryGetChar(src, end, &ch)) return -1; + if ('0' <= ch && ch <= '7') { + return ch - '0'; + } + *src -= 1; // Char wasn't actually an octal digit. + return -1; +} + +static char upb_DefBuilder_ParseOctalEscape(upb_DefBuilder* ctx, + const upb_FieldDef* f, + const char** src, const char* end) { + char ch = 0; + for (int i = 0; i < 3; i++) { + char digit; + if ((digit = TryGetOctalDigit(src, end)) >= 0) { + ch = (ch << 3) | digit; + } + } + return ch; +} + +char _upb_DefBuilder_ParseEscape(upb_DefBuilder* ctx, const upb_FieldDef* f, + const char** src, const char* end) { + char ch; + if (!TryGetChar(src, end, &ch)) { + _upb_DefBuilder_Errf(ctx, "unterminated escape sequence in field %s", + upb_FieldDef_FullName(f)); + return 0; + } + switch (ch) { + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '\"': + return '\"'; + case '?': + return '\?'; + case 'x': + case 'X': + return upb_DefBuilder_ParseHexEscape(ctx, f, src, end); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + *src -= 1; + return upb_DefBuilder_ParseOctalEscape(ctx, f, src, end); + } + _upb_DefBuilder_Errf(ctx, "Unknown escape sequence: \\%c", ch); +} + +void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, + bool full) { + const char* str = name.data; + const size_t len = name.size; + bool start = true; + for (size_t i = 0; i < len; i++) { + const char c = str[i]; + if (c == '.') { + if (start || !full) { + _upb_DefBuilder_Errf( + ctx, "invalid name: unexpected '.' (" UPB_STRINGVIEW_FORMAT ")", + UPB_STRINGVIEW_ARGS(name)); + } + start = true; + } else if (start) { + if (!upb_isletter(c)) { + _upb_DefBuilder_Errf(ctx, + "invalid name: path components must start with a " + "letter (" UPB_STRINGVIEW_FORMAT ")", + UPB_STRINGVIEW_ARGS(name)); + } + start = false; + } else if (!upb_isalphanum(c)) { + _upb_DefBuilder_Errf( + ctx, + "invalid name: non-alphanumeric character (" UPB_STRINGVIEW_FORMAT + ")", + UPB_STRINGVIEW_ARGS(name)); + } + } + if (start) { + _upb_DefBuilder_Errf(ctx, + "invalid name: empty part (" UPB_STRINGVIEW_FORMAT ")", + UPB_STRINGVIEW_ARGS(name)); + } + + // We should never reach this point. + UPB_ASSERT(false); +} + +upb_StringView _upb_DefBuilder_MakeKey(upb_DefBuilder* ctx, + const google_protobuf_FeatureSet* parent, + upb_StringView key) { + size_t need = key.size + sizeof(void*); + if (ctx->tmp_buf_size < need) { + ctx->tmp_buf_size = UPB_MAX(64, upb_RoundUpToPowerOfTwo(need)); + ctx->tmp_buf = upb_Arena_Malloc(ctx->tmp_arena, ctx->tmp_buf_size); + if (!ctx->tmp_buf) _upb_DefBuilder_OomErr(ctx); + } + + memcpy(ctx->tmp_buf, &parent, sizeof(void*)); + memcpy(ctx->tmp_buf + sizeof(void*), key.data, key.size); + return upb_StringView_FromDataAndSize(ctx->tmp_buf, need); +} + +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const google_protobuf_FeatureSet* parent, + upb_StringView key, + google_protobuf_FeatureSet** set) { + upb_StringView k = _upb_DefBuilder_MakeKey(ctx, parent, key); + upb_value v; + if (upb_strtable_lookup2(&ctx->feature_cache, k.data, k.size, &v)) { + *set = upb_value_getptr(v); + return false; + } + + *set = (google_protobuf_FeatureSet*)upb_Message_DeepClone( + UPB_UPCAST(parent), UPB_DESC_MINITABLE(FeatureSet), ctx->arena); + if (!*set) _upb_DefBuilder_OomErr(ctx); + + v = upb_value_ptr(*set); + if (!upb_strtable_insert(&ctx->feature_cache, k.data, k.size, v, + ctx->tmp_arena)) { + _upb_DefBuilder_OomErr(ctx); + } + + return true; +} + +const google_protobuf_FeatureSet* _upb_DefBuilder_DoResolveFeatures( + upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent, + const google_protobuf_FeatureSet* child, bool is_implicit) { + assert(parent); + if (!child) return parent; + + if (!is_implicit && + _upb_DefBuilder_IsLegacyEdition(upb_FileDef_Edition(ctx->file))) { + _upb_DefBuilder_Errf(ctx, "Features can only be specified for editions"); + } + + google_protobuf_FeatureSet* resolved; + size_t child_size; + const char* child_bytes = + google_protobuf_FeatureSet_serialize(child, ctx->tmp_arena, &child_size); + if (!child_bytes) _upb_DefBuilder_OomErr(ctx); + + upb_StringView key = upb_StringView_FromDataAndSize(child_bytes, child_size); + if (!_upb_DefBuilder_GetOrCreateFeatureSet(ctx, parent, key, &resolved)) { + return resolved; + } + + upb_DecodeStatus dec_status = + upb_Decode(child_bytes, child_size, UPB_UPCAST(resolved), + UPB_DESC_MINITABLE(FeatureSet), NULL, 0, ctx->arena); + if (dec_status != kUpb_DecodeStatus_Ok) _upb_DefBuilder_OomErr(ctx); + + return resolved; +} + + +#include <string.h> + + +// Must be last. + +char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { + size_t n; + char* p; + + // Prevent overflow errors. + if (len == SIZE_MAX) return NULL; + + // Always null-terminate, even if binary data; but don't rely on the input to + // have a null-terminating byte since it may be a raw binary buffer. + n = len + 1; + p = upb_Arena_Malloc(a, n); + if (p) { + if (len != 0) memcpy(p, s, len); + p[len] = 0; + } + return p; +} + + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +bool upb_Message_HasFieldByDef(const upb_Message* msg, const upb_FieldDef* f) { + const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f); + UPB_ASSERT(upb_FieldDef_HasPresence(f)); + + if (upb_MiniTableField_IsExtension(m_f)) { + return upb_Message_HasExtension(msg, (const upb_MiniTableExtension*)m_f); + } else { + return upb_Message_HasBaseField(msg, m_f); + } +} + +const upb_FieldDef* upb_Message_WhichOneofByDef(const upb_Message* msg, + const upb_OneofDef* o) { + const upb_FieldDef* f = upb_OneofDef_Field(o, 0); + if (upb_OneofDef_IsSynthetic(o)) { + UPB_ASSERT(upb_OneofDef_FieldCount(o) == 1); + return upb_Message_HasFieldByDef(msg, f) ? f : NULL; + } else { + const upb_MiniTableField* field = upb_FieldDef_MiniTable(f); + uint32_t oneof_case = upb_Message_WhichOneofFieldNumber(msg, field); + f = oneof_case ? upb_OneofDef_LookupNumber(o, oneof_case) : NULL; + UPB_ASSERT((f != NULL) == (oneof_case != 0)); + return f; + } +} + +upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, + const upb_FieldDef* f) { + upb_MessageValue default_val = upb_FieldDef_Default(f); + return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val); +} + +upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(upb_FieldDef_IsSubMessage(f) || upb_FieldDef_IsRepeated(f)); + if (upb_FieldDef_HasPresence(f) && !upb_Message_HasFieldByDef(msg, f)) { + // We need to skip the upb_Message_GetFieldByDef() call in this case. + goto make; + } + + upb_MessageValue val = upb_Message_GetFieldByDef(msg, f); + if (val.array_val) { + return (upb_MutableMessageValue){.array = (upb_Array*)val.array_val}; + } + + upb_MutableMessageValue ret; +make: + if (!a) return (upb_MutableMessageValue){.array = NULL}; + if (upb_FieldDef_IsMap(f)) { + const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f); + const upb_FieldDef* key = + upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_KeyFieldNumber); + const upb_FieldDef* value = + upb_MessageDef_FindFieldByNumber(entry, kUpb_MapEntry_ValueFieldNumber); + ret.map = + upb_Map_New(a, upb_FieldDef_CType(key), upb_FieldDef_CType(value)); + } else if (upb_FieldDef_IsRepeated(f)) { + ret.array = upb_Array_New(a, upb_FieldDef_CType(f)); + } else { + UPB_ASSERT(upb_FieldDef_IsSubMessage(f)); + const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); + ret.msg = upb_Message_New(upb_MessageDef_MiniTable(m), a); + } + + val.array_val = ret.array; + upb_Message_SetFieldByDef(msg, f, val, a); + + return ret; +} + +bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f); + + if (upb_MiniTableField_IsExtension(m_f)) { + return upb_Message_SetExtension(msg, (const upb_MiniTableExtension*)m_f, + &val, a); + } else { + upb_Message_SetBaseField(msg, m_f, &val); + return true; + } +} + +void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + const upb_MiniTableField* m_f = upb_FieldDef_MiniTable(f); + + if (upb_MiniTableField_IsExtension(m_f)) { + upb_Message_ClearExtension(msg, (const upb_MiniTableExtension*)m_f); + } else { + upb_Message_ClearBaseField(msg, m_f); + } +} + +void upb_Message_ClearByDef(upb_Message* msg, const upb_MessageDef* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Clear(msg, upb_MessageDef_MiniTable(m)); +} + +bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, const upb_FieldDef** out_f, + upb_MessageValue* out_val, size_t* iter) { + const upb_MiniTable* mt = upb_MessageDef_MiniTable(m); + size_t i = *iter; + size_t n = upb_MiniTable_FieldCount(mt); + upb_MessageValue zero = upb_MessageValue_Zero(); + UPB_UNUSED(ext_pool); + + // Iterate over normal fields, returning the first one that is set. + while (++i < n) { + const upb_MiniTableField* field = upb_MiniTable_GetFieldByIndex(mt, i); + upb_MessageValue val = upb_Message_GetField(msg, field, zero); + + // Skip field if unset or empty. + if (upb_MiniTableField_HasPresence(field)) { + if (!upb_Message_HasBaseField(msg, field)) continue; + } else { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { + case kUpb_FieldMode_Map: + if (!val.map_val || upb_Map_Size(val.map_val) == 0) continue; + break; + case kUpb_FieldMode_Array: + if (!val.array_val || upb_Array_Size(val.array_val) == 0) continue; + break; + case kUpb_FieldMode_Scalar: + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, &val)) + continue; + break; + } + } + + *out_val = val; + *out_f = + upb_MessageDef_FindFieldByNumber(m, upb_MiniTableField_Number(field)); + *iter = i; + return true; + } + + if (ext_pool) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return false; + + for (; (i - n) < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i - n]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + memcpy(out_val, &ext->data, sizeof(*out_val)); + *out_f = upb_DefPool_FindExtensionByMiniTable(ext_pool, ext->ext); + *iter = i; + return true; + } + } + } + + *iter = i; + return false; +} + +bool _upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int depth) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + size_t iter = kUpb_Message_Begin; + const upb_FieldDef* f; + upb_MessageValue val; + bool ret = true; + + if (--depth == 0) return false; + + _upb_Message_DiscardUnknown_shallow(msg); + + while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { + const upb_MessageDef* subm = upb_FieldDef_MessageSubDef(f); + if (!subm) continue; + if (upb_FieldDef_IsMap(f)) { + const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(subm, 2); + const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f); + upb_Map* map = (upb_Map*)val.map_val; + size_t iter = kUpb_Map_Begin; + + if (!val_m) continue; + + upb_MessageValue map_key, map_val; + while (upb_Map_Next(map, &map_key, &map_val, &iter)) { + if (!_upb_Message_DiscardUnknown((upb_Message*)map_val.msg_val, val_m, + ext_pool, depth)) { + ret = false; + } + } + } else if (upb_FieldDef_IsRepeated(f)) { + const upb_Array* arr = val.array_val; + size_t i, n = upb_Array_Size(arr); + for (i = 0; i < n; i++) { + upb_MessageValue elem = upb_Array_Get(arr, i); + if (!_upb_Message_DiscardUnknown((upb_Message*)elem.msg_val, subm, + ext_pool, depth)) { + ret = false; + } + } + } else { + if (!_upb_Message_DiscardUnknown((upb_Message*)val.msg_val, subm, + ext_pool, depth)) { + ret = false; + } + } + } + + return ret; +} + +bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int maxdepth) { + return _upb_Message_DiscardUnknown(msg, m, ext_pool, maxdepth); +} + + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +struct upb_MessageDef { + UPB_ALIGN_AS(8) const google_protobuf_MessageOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_MiniTable* layout; + const upb_FileDef* file; + const upb_MessageDef* containing_type; + const char* full_name; + + // Tables for looking up fields by number and name. + upb_inttable itof; + upb_strtable ntof; + + // Looking up fields by json name. + upb_strtable jtof; + + /* All nested defs. + * MEM: We could save some space here by putting nested defs in a contiguous + * region and calculating counts from offsets or vice-versa. */ + const upb_FieldDef* fields; + const upb_OneofDef* oneofs; + const upb_ExtensionRange* ext_ranges; + const upb_StringView* res_names; + const upb_MessageDef* nested_msgs; + const upb_MessageReservedRange* res_ranges; + const upb_EnumDef* nested_enums; + const upb_FieldDef* nested_exts; + + // TODO: These counters don't need anywhere near 32 bits. + int field_count; + int real_oneof_count; + int oneof_count; + int ext_range_count; + int res_range_count; + int res_name_count; + int nested_msg_count; + int nested_enum_count; + int nested_ext_count; + bool in_message_set; + bool is_sorted; + upb_WellKnown well_known_type; + google_protobuf_SymbolVisibility visibility; +}; + +static void assign_msg_wellknowntype(upb_MessageDef* m) { + const char* name = m->full_name; + if (name == NULL) { + m->well_known_type = kUpb_WellKnown_Unspecified; + return; + } + if (!strcmp(name, "google.protobuf.Any")) { + m->well_known_type = kUpb_WellKnown_Any; + } else if (!strcmp(name, "google.protobuf.FieldMask")) { + m->well_known_type = kUpb_WellKnown_FieldMask; + } else if (!strcmp(name, "google.protobuf.Duration")) { + m->well_known_type = kUpb_WellKnown_Duration; + } else if (!strcmp(name, "google.protobuf.Timestamp")) { + m->well_known_type = kUpb_WellKnown_Timestamp; + } else if (!strcmp(name, "google.protobuf.DoubleValue")) { + m->well_known_type = kUpb_WellKnown_DoubleValue; + } else if (!strcmp(name, "google.protobuf.FloatValue")) { + m->well_known_type = kUpb_WellKnown_FloatValue; + } else if (!strcmp(name, "google.protobuf.Int64Value")) { + m->well_known_type = kUpb_WellKnown_Int64Value; + } else if (!strcmp(name, "google.protobuf.UInt64Value")) { + m->well_known_type = kUpb_WellKnown_UInt64Value; + } else if (!strcmp(name, "google.protobuf.Int32Value")) { + m->well_known_type = kUpb_WellKnown_Int32Value; + } else if (!strcmp(name, "google.protobuf.UInt32Value")) { + m->well_known_type = kUpb_WellKnown_UInt32Value; + } else if (!strcmp(name, "google.protobuf.BoolValue")) { + m->well_known_type = kUpb_WellKnown_BoolValue; + } else if (!strcmp(name, "google.protobuf.StringValue")) { + m->well_known_type = kUpb_WellKnown_StringValue; + } else if (!strcmp(name, "google.protobuf.BytesValue")) { + m->well_known_type = kUpb_WellKnown_BytesValue; + } else if (!strcmp(name, "google.protobuf.Value")) { + m->well_known_type = kUpb_WellKnown_Value; + } else if (!strcmp(name, "google.protobuf.ListValue")) { + m->well_known_type = kUpb_WellKnown_ListValue; + } else if (!strcmp(name, "google.protobuf.Struct")) { + m->well_known_type = kUpb_WellKnown_Struct; + } else { + m->well_known_type = kUpb_WellKnown_Unspecified; + } +} + +upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i) { + return (upb_MessageDef*)&m[i]; +} + +bool _upb_MessageDef_IsValidExtensionNumber(const upb_MessageDef* m, int n) { + for (int i = 0; i < m->ext_range_count; i++) { + const upb_ExtensionRange* r = upb_MessageDef_ExtensionRange(m, i); + if (upb_ExtensionRange_Start(r) <= n && n < upb_ExtensionRange_End(r)) { + return true; + } + } + return false; +} + +const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m) { + return m->opts; +} + +bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { + return m->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_MessageDef_ResolvedFeatures( + const upb_MessageDef* m) { + return m->resolved_features; +} + +const char* upb_MessageDef_FullName(const upb_MessageDef* m) { + return m->full_name; +} + +const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) { + return m->file; +} + +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) { + return m->containing_type; +} + +const char* upb_MessageDef_Name(const upb_MessageDef* m) { + return _upb_DefBuilder_FullToShort(m->full_name); +} + +const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m, + uint32_t i) { + upb_value val; + return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val) + : NULL; +} + +const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); +} + +const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); +} + +bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t len, + upb_value v, upb_Arena* a) { + return upb_strtable_insert(&m->ntof, name, len, v, a); +} + +bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t len, + const upb_FieldDef** out_f, + const upb_OneofDef** out_o) { + upb_value val; + + if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { + return false; + } + + const upb_FieldDef* f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); + const upb_OneofDef* o = _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); + if (out_f) *out_f = f; + if (out_o) *out_o = o; + return f || o; /* False if this was a JSON name. */ +} + +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t size) { + upb_value val; + + if (upb_strtable_lookup2(&m->jtof, name, size, &val)) { + return upb_value_getconstptr(val); + } + + if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); +} + +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) { + return m->ext_range_count; +} + +int upb_MessageDef_ReservedRangeCount(const upb_MessageDef* m) { + return m->res_range_count; +} + +int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m) { + return m->res_name_count; +} + +int upb_MessageDef_FieldCount(const upb_MessageDef* m) { + return m->field_count; +} + +int upb_MessageDef_OneofCount(const upb_MessageDef* m) { + return m->oneof_count; +} + +int upb_MessageDef_RealOneofCount(const upb_MessageDef* m) { + return m->real_oneof_count; +} + +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) { + return m->nested_msg_count; +} + +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) { + return m->nested_enum_count; +} + +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) { + return m->nested_ext_count; +} + +const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) { + return m->layout; +} + +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->ext_range_count); + return _upb_ExtensionRange_At(m->ext_ranges, i); +} + +const upb_MessageReservedRange* upb_MessageDef_ReservedRange( + const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->res_range_count); + return _upb_MessageReservedRange_At(m->res_ranges, i); +} + +upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->res_name_count); + return m->res_names[i]; +} + +const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->field_count); + return _upb_FieldDef_At(m->fields, i); +} + +const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->oneof_count); + return _upb_OneofDef_At(m->oneofs, i); +} + +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_msg_count); + return &m->nested_msgs[i]; +} + +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) { + UPB_ASSERT(0 <= i && i < m->nested_enum_count); + return _upb_EnumDef_At(m->nested_enums, i); +} + +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i) { + UPB_ASSERT(0 <= i && i < m->nested_ext_count); + return _upb_FieldDef_At(m->nested_exts, i); +} + +upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { + return m->well_known_type; +} + +UPB_API google_protobuf_SymbolVisibility +upb_MessageDef_Visibility(const upb_MessageDef* m) { + return m->visibility; +} + +bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m) { + return m->in_message_set; +} + +const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, + const char* name) { + return upb_MessageDef_FindFieldByNameWithSize(m, name, strlen(name)); +} + +const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, + const char* name) { + return upb_MessageDef_FindOneofByNameWithSize(m, name, strlen(name)); +} + +bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) { + return google_protobuf_MessageOptions_map_entry(m->opts); +} + +bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m) { + return google_protobuf_MessageOptions_message_set_wire_format(m->opts); +} + +static upb_MiniTable* _upb_MessageDef_MakeMiniTable(upb_DefBuilder* ctx, + const upb_MessageDef* m) { + upb_StringView desc; + // Note: this will assign layout_index for fields, so upb_FieldDef_MiniTable() + // is safe to call only after this call. + bool ok = upb_MessageDef_MiniDescriptorEncode(m, ctx->tmp_arena, &desc); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + void** scratch_data = _upb_DefPool_ScratchData(ctx->symtab); + size_t* scratch_size = _upb_DefPool_ScratchSize(ctx->symtab); + upb_MiniTable* ret = upb_MiniTable_BuildWithBuf( + desc.data, desc.size, ctx->platform, ctx->arena, scratch_data, + scratch_size, ctx->status); + if (!ret) _upb_DefBuilder_FailJmp(ctx); + + return ret; +} + +void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m) { + for (int i = 0; i < m->field_count; i++) { + upb_FieldDef* f = (upb_FieldDef*)upb_MessageDef_Field(m, i); + _upb_FieldDef_Resolve(ctx, m->full_name, f); + } + + m->in_message_set = false; + for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { + upb_FieldDef* ext = (upb_FieldDef*)upb_MessageDef_NestedExtension(m, i); + _upb_FieldDef_Resolve(ctx, m->full_name, ext); + if (upb_FieldDef_Type(ext) == kUpb_FieldType_Message && + upb_FieldDef_Label(ext) == kUpb_Label_Optional && + upb_FieldDef_MessageSubDef(ext) == m && + google_protobuf_MessageOptions_message_set_wire_format( + upb_MessageDef_Options(upb_FieldDef_ContainingType(ext)))) { + m->in_message_set = true; + } + } + + for (int i = 0; i < upb_MessageDef_NestedMessageCount(m); i++) { + upb_MessageDef* n = (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); + _upb_MessageDef_Resolve(ctx, n); + } +} + +void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, + const upb_FieldDef* f) { + const int32_t field_number = upb_FieldDef_Number(f); + + if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) { + _upb_DefBuilder_Errf(ctx, "invalid field number (%u)", field_number); + } + + const char* json_name = upb_FieldDef_JsonName(f); + const char* shortname = upb_FieldDef_Name(f); + const size_t shortnamelen = strlen(shortname); + + upb_value v = upb_value_constptr(f); + + upb_value existing_v; + if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) { + _upb_DefBuilder_Errf(ctx, "duplicate field name (%s)", shortname); + } + + const upb_value field_v = _upb_DefType_Pack(f, UPB_DEFTYPE_FIELD); + bool ok = + _upb_MessageDef_Insert(m, shortname, shortnamelen, field_v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + bool skip_json_conflicts = + google_protobuf_MessageOptions_deprecated_legacy_json_field_conflicts( + upb_MessageDef_Options(m)); + if (!skip_json_conflicts && strcmp(shortname, json_name) != 0 && + google_protobuf_FeatureSet_json_format(m->resolved_features) == + google_protobuf_FeatureSet_ALLOW && + upb_strtable_lookup(&m->ntof, json_name, &v)) { + _upb_DefBuilder_Errf( + ctx, "duplicate json_name for (%s) with original field name (%s)", + shortname, json_name); + } + + if (upb_strtable_lookup(&m->jtof, json_name, &v)) { + if (!skip_json_conflicts) { + _upb_DefBuilder_Errf(ctx, "duplicate json_name (%s)", json_name); + } + } else { + const size_t json_size = strlen(json_name); + ok = upb_strtable_insert(&m->jtof, json_name, json_size, + upb_value_constptr(f), ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + } + + if (upb_inttable_lookup(&m->itof, field_number, NULL)) { + _upb_DefBuilder_Errf(ctx, "duplicate field number (%u)", field_number); + } + + ok = upb_inttable_insert(&m->itof, field_number, v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { + if (ctx->layout == NULL) { + m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); + } else { + m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++); + UPB_ASSERT(m->field_count == upb_MiniTable_FieldCount(m->layout)); + + // We don't need the result of this call, but it will assign layout_index + // for all the fields in O(n lg n) time. + _upb_FieldDefs_Sorted(m->fields, m->field_count, ctx->tmp_arena); + } + + for (int i = 0; i < m->nested_msg_count; i++) { + upb_MessageDef* nested = + (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); + _upb_MessageDef_CreateMiniTable(ctx, nested); + } +} + +void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, + const upb_MessageDef* m) { + for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { + const upb_FieldDef* ext = upb_MessageDef_NestedExtension(m, i); + _upb_FieldDef_BuildMiniTableExtension(ctx, ext); + } + + for (int i = 0; i < m->nested_msg_count; i++) { + _upb_MessageDef_LinkMiniTable(ctx, upb_MessageDef_NestedMessage(m, i)); + } + + if (ctx->layout || ctx->platform != kUpb_MiniTablePlatform_Native) return; + + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + const upb_MessageDef* sub_m = upb_FieldDef_MessageSubDef(f); + const upb_EnumDef* sub_e = upb_FieldDef_EnumSubDef(f); + const int layout_index = _upb_FieldDef_LayoutIndex(f); + upb_MiniTable* mt = (upb_MiniTable*)upb_MessageDef_MiniTable(m); + + UPB_ASSERT(layout_index < m->field_count); + upb_MiniTableField* mt_f = + (upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index]; + if (sub_m) { + UPB_ASSERT(mt_f); + UPB_ASSERT(sub_m->layout); + if (UPB_UNLIKELY(!upb_MiniTable_SetSubMessage(mt, mt_f, sub_m->layout))) { + _upb_DefBuilder_Errf(ctx, "invalid submsg for (%s)", m->full_name); + } + } else if (_upb_FieldDef_IsClosedEnum(f)) { + const upb_MiniTableEnum* mt_e = _upb_EnumDef_MiniTable(sub_e); + if (UPB_UNLIKELY(!upb_MiniTable_SetSubEnum(mt, mt_f, mt_e))) { + _upb_DefBuilder_Errf(ctx, "invalid subenum for (%s)", m->full_name); + } + } + } + +#ifndef NDEBUG + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + const int layout_index = _upb_FieldDef_LayoutIndex(f); + UPB_ASSERT(layout_index < upb_MiniTable_FieldCount(m->layout)); + const upb_MiniTableField* mt_f = + &m->layout->UPB_PRIVATE(fields)[layout_index]; + UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); + UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f)); + UPB_ASSERT(upb_FieldDef_HasPresence(f) == + upb_MiniTableField_HasPresence(mt_f)); + } +#endif +} + +// Returns whether packable repeated fields in the message should be considered +// packed by default. This is used only for the purpose of encoding +// MiniDescriptors, so we just return true if there are more packed fields than +// unpacked. This optimizes for smaller MiniDescriptors. +static bool _upb_MessageDef_DefaultIsPacked(const upb_MessageDef* m) { + int packed = 0; + int unpacked = 0; + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + if (_upb_FieldDef_IsPackable(f)) { + if (upb_FieldDef_IsPacked(f)) { + ++packed; + } else { + ++unpacked; + } + } + } + return packed > unpacked; +} + +static bool _upb_MessageDef_ValidateUtf8(const upb_MessageDef* m) { + bool has_string = false; + for (int i = 0; i < m->field_count; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + // Old binaries do not recognize the field-level "FlipValidateUtf8" wire + // modifier, so we do not actually have field-level control for old + // binaries. Given this, we judge that the better failure mode is to be + // more lax than intended, rather than more strict. To achieve this, we + // only mark the message with the ValidateUtf8 modifier if *all* fields + // validate UTF-8. + if (!_upb_FieldDef_ValidateUtf8(f)) return false; + if (upb_FieldDef_Type(f) == kUpb_FieldType_String) has_string = true; + } + return has_string; +} + +static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) { + uint64_t out = 0; + + if (_upb_MessageDef_DefaultIsPacked(m)) { + out |= kUpb_MessageModifier_DefaultIsPacked; + } + + if (_upb_MessageDef_ValidateUtf8(m)) { + out |= kUpb_MessageModifier_ValidateUtf8; + } + + if (m->ext_range_count) { + out |= kUpb_MessageModifier_IsExtendable; + } + + return out; +} + +static bool _upb_MessageDef_EncodeMap(upb_DescState* s, const upb_MessageDef* m, + upb_Arena* a) { + if (m->field_count != 2) return false; + + const upb_FieldDef* key_field = upb_MessageDef_Field(m, 0); + const upb_FieldDef* val_field = upb_MessageDef_Field(m, 1); + if (key_field == NULL || val_field == NULL) return false; + + UPB_ASSERT(_upb_FieldDef_LayoutIndex(key_field) == 0); + UPB_ASSERT(_upb_FieldDef_LayoutIndex(val_field) == 1); + + s->ptr = upb_MtDataEncoder_EncodeMap( + &s->e, s->ptr, upb_FieldDef_Type(key_field), upb_FieldDef_Type(val_field), + _upb_FieldDef_Modifiers(key_field), _upb_FieldDef_Modifiers(val_field)); + return true; +} + +static bool _upb_MessageDef_EncodeMessage(upb_DescState* s, + const upb_MessageDef* m, + upb_Arena* a) { + const upb_FieldDef** sorted = NULL; + if (!m->is_sorted) { + sorted = _upb_FieldDefs_Sorted(m->fields, m->field_count, a); + if (!sorted) 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->real_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); + } + } + + return true; +} + +static bool _upb_MessageDef_EncodeMessageSet(upb_DescState* s, + const upb_MessageDef* m, + upb_Arena* a) { + s->ptr = upb_MtDataEncoder_EncodeMessageSet(&s->e, s->ptr); + + return true; +} + +bool upb_MessageDef_MiniDescriptorEncode(const upb_MessageDef* m, upb_Arena* a, + upb_StringView* out) { + upb_DescState s; + _upb_DescState_Init(&s); + + if (!_upb_DescState_Grow(&s, a)) return false; + + if (upb_MessageDef_IsMapEntry(m)) { + if (!_upb_MessageDef_EncodeMap(&s, m, a)) return false; + } else if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) { + if (!_upb_MessageDef_EncodeMessageSet(&s, m, a)) return false; + } else { + if (!_upb_MessageDef_EncodeMessage(&s, m, a)) return false; + } + + if (!_upb_DescState_Grow(&s, a)) return false; + *s.ptr = '\0'; + + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; +} + +static upb_StringView* _upb_ReservedNames_New(upb_DefBuilder* ctx, int n, + const upb_StringView* protos) { + upb_StringView* sv = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_StringView, n); + for (int i = 0; i < n; i++) { + sv[i].data = + upb_strdup2(protos[i].data, protos[i].size, _upb_DefBuilder_Arena(ctx)); + sv[i].size = protos[i].size; + } + return sv; +} + +static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, + const google_protobuf_DescriptorProto* msg_proto, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type, + upb_MessageDef* m) { + const google_protobuf_OneofDescriptorProto* const* oneofs; + const google_protobuf_FieldDescriptorProto* const* fields; + const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges; + const google_protobuf_DescriptorProto_ReservedRange* const* res_ranges; + const upb_StringView* res_names; + size_t n_oneof, n_field, n_enum, n_ext, n_msg; + size_t n_ext_range, n_res_range, n_res_name; + upb_StringView name; + + UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_MessageOptions_features(m->opts)); + + // Must happen before _upb_DefBuilder_Add() + m->file = _upb_DefBuilder_File(ctx); + + m->containing_type = containing_type; + m->is_sorted = true; + + name = google_protobuf_DescriptorProto_name(msg_proto); + + m->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); + _upb_DefBuilder_Add(ctx, m->full_name, _upb_DefType_Pack(m, UPB_DEFTYPE_MSG)); + + oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof); + fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field); + ext_ranges = google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range); + res_ranges = google_protobuf_DescriptorProto_reserved_range(msg_proto, &n_res_range); + res_names = google_protobuf_DescriptorProto_reserved_name(msg_proto, &n_res_name); + + bool ok = upb_inttable_init(&m->itof, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_strtable_init(&m->jtof, n_field, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + m->oneof_count = n_oneof; + m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m->resolved_features, m); + + m->field_count = n_field; + m->fields = _upb_FieldDefs_New(ctx, n_field, fields, m->resolved_features, + m->full_name, m, &m->is_sorted); + + // Message Sets may not contain fields. + if (UPB_UNLIKELY(google_protobuf_MessageOptions_message_set_wire_format(m->opts))) { + if (UPB_UNLIKELY(n_field > 0)) { + _upb_DefBuilder_Errf(ctx, "invalid message set (%s)", m->full_name); + } + } + + m->ext_range_count = n_ext_range; + m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, + m->resolved_features, m); + + m->res_range_count = n_res_range; + m->res_ranges = + _upb_MessageReservedRanges_New(ctx, n_res_range, res_ranges, m); + + m->res_name_count = n_res_name; + m->res_names = _upb_ReservedNames_New(ctx, n_res_name, res_names); + + const size_t synthetic_count = _upb_OneofDefs_Finalize(ctx, m); + m->real_oneof_count = m->oneof_count - synthetic_count; + + assign_msg_wellknowntype(m); + if (!upb_inttable_compact(&m->itof, ctx->arena)) _upb_DefBuilder_OomErr(ctx); + + const google_protobuf_EnumDescriptorProto* const* enums = + google_protobuf_DescriptorProto_enum_type(msg_proto, &n_enum); + m->nested_enum_count = n_enum; + m->nested_enums = + _upb_EnumDefs_New(ctx, n_enum, enums, m->resolved_features, m); + + const google_protobuf_FieldDescriptorProto* const* exts = + google_protobuf_DescriptorProto_extension(msg_proto, &n_ext); + m->nested_ext_count = n_ext; + m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->resolved_features, + m->full_name, m); + + const google_protobuf_DescriptorProto* const* msgs = + google_protobuf_DescriptorProto_nested_type(msg_proto, &n_msg); + m->nested_msg_count = n_msg; + m->nested_msgs = + _upb_MessageDefs_New(ctx, n_msg, msgs, m->resolved_features, m); + + m->visibility = google_protobuf_DescriptorProto_visibility(msg_proto); +} + +// Allocate and initialize an array of |n| message defs. +upb_MessageDef* _upb_MessageDefs_New( + upb_DefBuilder* ctx, int n, const google_protobuf_DescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type) { + _upb_DefType_CheckPadding(sizeof(upb_MessageDef)); + + const char* name = containing_type ? containing_type->full_name + : _upb_FileDef_RawPackage(ctx->file); + + upb_MessageDef* m = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MessageDef, n); + for (int i = 0; i < n; i++) { + create_msgdef(ctx, name, protos[i], parent_features, containing_type, + &m[i]); + } + return m; +} + +#include <stdint.h> + + +// Must be last. + +struct upb_MessageReservedRange { + int32_t start; + int32_t end; +}; + +upb_MessageReservedRange* _upb_MessageReservedRange_At( + const upb_MessageReservedRange* r, int i) { + return (upb_MessageReservedRange*)&r[i]; +} + +int32_t upb_MessageReservedRange_Start(const upb_MessageReservedRange* r) { + return r->start; +} +int32_t upb_MessageReservedRange_End(const upb_MessageReservedRange* r) { + return r->end; +} + +upb_MessageReservedRange* _upb_MessageReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ReservedRange* const* protos, + const upb_MessageDef* m) { + upb_MessageReservedRange* r = + UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MessageReservedRange, n); + + for (int i = 0; i < n; i++) { + const int32_t start = google_protobuf_DescriptorProto_ReservedRange_start(protos[i]); + const int32_t end = google_protobuf_DescriptorProto_ReservedRange_end(protos[i]); + const int32_t max = kUpb_MaxFieldNumber + 1; + + // A full validation would also check that each range is disjoint, and that + // none of the fields overlap with the extension ranges, but we are just + // sanity checking here. + if (start < 1 || end <= start || end > max) { + _upb_DefBuilder_Errf(ctx, + "Reserved range (%d, %d) is invalid, message=%s\n", + (int)start, (int)end, upb_MessageDef_FullName(m)); + } + + r[i].start = start; + r[i].end = end; + } + + return r; +} + + + +// Must be last. + +struct upb_MethodDef { + const google_protobuf_MethodOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + upb_ServiceDef* service; + const char* full_name; + const upb_MessageDef* input_type; + const upb_MessageDef* output_type; + int index; + bool client_streaming; + bool server_streaming; +}; + +upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i) { + return (upb_MethodDef*)&m[i]; +} + +const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) { + return m->service; +} + +const google_protobuf_MethodOptions* upb_MethodDef_Options(const upb_MethodDef* m) { + return m->opts; +} + +bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { + return m->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_MethodDef_ResolvedFeatures( + const upb_MethodDef* m) { + return m->resolved_features; +} + +const char* upb_MethodDef_FullName(const upb_MethodDef* m) { + return m->full_name; +} + +const char* upb_MethodDef_Name(const upb_MethodDef* m) { + return _upb_DefBuilder_FullToShort(m->full_name); +} + +int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; } + +const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) { + return m->input_type; +} + +const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) { + return m->output_type; +} + +bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) { + return m->client_streaming; +} + +bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { + return m->server_streaming; +} + +static void create_method(upb_DefBuilder* ctx, + const google_protobuf_MethodDescriptorProto* method_proto, + const google_protobuf_FeatureSet* parent_features, + upb_ServiceDef* s, upb_MethodDef* m) { + UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, + method_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_MethodOptions_features(m->opts)); + + upb_StringView name = google_protobuf_MethodDescriptorProto_name(method_proto); + + m->service = s; + m->full_name = + _upb_DefBuilder_MakeFullName(ctx, upb_ServiceDef_FullName(s), name); + m->client_streaming = + google_protobuf_MethodDescriptorProto_client_streaming(method_proto); + m->server_streaming = + google_protobuf_MethodDescriptorProto_server_streaming(method_proto); + m->input_type = _upb_DefBuilder_Resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_input_type(method_proto), UPB_DEFTYPE_MSG); + m->output_type = _upb_DefBuilder_Resolve( + ctx, m->full_name, m->full_name, + google_protobuf_MethodDescriptorProto_output_type(method_proto), UPB_DEFTYPE_MSG); + _upb_ServiceDef_InsertMethod(ctx, s, m); +} + +// Allocate and initialize an array of |n| method defs belonging to |s|. +upb_MethodDef* _upb_MethodDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_MethodDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_ServiceDef* s) { + upb_MethodDef* m = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MethodDef, n); + for (int i = 0; i < n; i++) { + create_method(ctx, protos[i], parent_features, s, &m[i]); + m[i].index = i; + } + return m; +} + + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Must be last. + +struct upb_OneofDef { + UPB_ALIGN_AS(8) const google_protobuf_OneofOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_MessageDef* parent; + const char* full_name; + int field_count; + bool synthetic; + const upb_FieldDef** fields; + upb_strtable ntof; // lookup a field by name + upb_inttable itof; // lookup a field by number (index) +}; + +upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i) { + return (upb_OneofDef*)&o[i]; +} + +const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o) { + return o->opts; +} + +bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { + return o->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o) { + return o->resolved_features; +} + +const char* upb_OneofDef_FullName(const upb_OneofDef* o) { + return o->full_name; +} + +const char* upb_OneofDef_Name(const upb_OneofDef* o) { + return _upb_DefBuilder_FullToShort(o->full_name); +} + +const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { + return o->parent; +} + +int upb_OneofDef_FieldCount(const upb_OneofDef* o) { return o->field_count; } + +const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i) { + UPB_ASSERT(i < o->field_count); + return o->fields[i]; +} + +int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; } + +uint32_t upb_OneofDef_Index(const upb_OneofDef* o) { + // Compute index in our parent's array. + return o - upb_MessageDef_Oneof(o->parent, 0); +} + +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; } + +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t size) { + upb_value val; + return upb_strtable_lookup2(&o->ntof, name, size, &val) + ? upb_value_getptr(val) + : NULL; +} + +const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, + const char* name) { + return upb_OneofDef_LookupNameWithSize(o, name, strlen(name)); +} + +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num) { + upb_value val; + return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) + : NULL; +} + +void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o, + const upb_FieldDef* f, const char* name, + size_t size) { + o->field_count++; + if (_upb_FieldDef_IsProto3Optional(f)) o->synthetic = true; + + const int number = upb_FieldDef_Number(f); + const upb_value v = upb_value_constptr(f); + + // TODO: This lookup is unfortunate because we also perform it when + // inserting into the message's table. Unfortunately that step occurs after + // this one and moving things around could be tricky so let's leave it for + // a future refactoring. + const bool number_exists = upb_inttable_lookup(&o->itof, number, NULL); + if (UPB_UNLIKELY(number_exists)) { + _upb_DefBuilder_Errf(ctx, "oneof fields have the same number (%d)", number); + } + + // TODO: More redundant work happening here. + const bool name_exists = upb_strtable_lookup2(&o->ntof, name, size, NULL); + if (UPB_UNLIKELY(name_exists)) { + _upb_DefBuilder_Errf(ctx, "oneof fields have the same name (%.*s)", + (int)size, name); + } + + const bool ok = upb_inttable_insert(&o->itof, number, v, ctx->arena) && + upb_strtable_insert(&o->ntof, name, size, v, ctx->arena); + if (UPB_UNLIKELY(!ok)) { + _upb_DefBuilder_OomErr(ctx); + } +} + +// Returns the synthetic count. +size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m) { + int synthetic_count = 0; + + for (int i = 0; i < upb_MessageDef_OneofCount(m); i++) { + upb_OneofDef* o = (upb_OneofDef*)upb_MessageDef_Oneof(m, i); + + if (o->synthetic && o->field_count != 1) { + _upb_DefBuilder_Errf(ctx, + "Synthetic oneofs must have one field, not %d: %s", + o->field_count, upb_OneofDef_Name(o)); + } + + if (o->synthetic) { + synthetic_count++; + } else if (synthetic_count != 0) { + _upb_DefBuilder_Errf( + ctx, "Synthetic oneofs must be after all other oneofs: %s", + upb_OneofDef_Name(o)); + } + + o->fields = + UPB_DEFBUILDER_ALLOCARRAY(ctx, const upb_FieldDef*, o->field_count); + o->field_count = 0; + } + + for (int i = 0; i < upb_MessageDef_FieldCount(m); i++) { + const upb_FieldDef* f = upb_MessageDef_Field(m, i); + upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f); + if (o) { + o->fields[o->field_count++] = f; + } + } + + return synthetic_count; +} + +static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, + const google_protobuf_OneofDescriptorProto* oneof_proto, + const google_protobuf_FeatureSet* parent_features, + const upb_OneofDef* _o) { + upb_OneofDef* o = (upb_OneofDef*)_o; + + UPB_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); + o->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_OneofOptions_features(o->opts)); + + upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto); + + o->parent = m; + o->full_name = + _upb_DefBuilder_MakeFullName(ctx, upb_MessageDef_FullName(m), name); + o->field_count = 0; + o->synthetic = false; + + if (upb_MessageDef_FindByNameWithSize(m, name.data, name.size, NULL, NULL)) { + _upb_DefBuilder_Errf(ctx, "duplicate oneof name (%s)", o->full_name); + } + + upb_value v = _upb_DefType_Pack(o, UPB_DEFTYPE_ONEOF); + bool ok = _upb_MessageDef_Insert(m, name.data, name.size, v, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_inttable_init(&o->itof, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + + ok = upb_strtable_init(&o->ntof, 4, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + +// Allocate and initialize an array of |n| oneof defs. +upb_OneofDef* _upb_OneofDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_OneofDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_MessageDef* m) { + _upb_DefType_CheckPadding(sizeof(upb_OneofDef)); + + upb_OneofDef* o = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_OneofDef, n); + for (int i = 0; i < n; i++) { + create_oneofdef(ctx, m, protos[i], parent_features, &o[i]); + } + return o; +} + + +#include <stddef.h> +#include <string.h> + + +// Must be last. + +struct upb_ServiceDef { + UPB_ALIGN_AS(8) const google_protobuf_ServiceOptions* opts; + const google_protobuf_FeatureSet* resolved_features; + const upb_FileDef* file; + const char* full_name; + upb_MethodDef* methods; + int method_count; + int index; + upb_strtable ntom; +}; + +upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) { + return (upb_ServiceDef*)&s[index]; +} + +const google_protobuf_ServiceOptions* upb_ServiceDef_Options(const upb_ServiceDef* s) { + return s->opts; +} + +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { + return s->opts != (void*)kUpbDefOptDefault; +} + +const google_protobuf_FeatureSet* upb_ServiceDef_ResolvedFeatures( + const upb_ServiceDef* s) { + return s->resolved_features; +} + +const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { + return s->full_name; +} + +const char* upb_ServiceDef_Name(const upb_ServiceDef* s) { + return _upb_DefBuilder_FullToShort(s->full_name); +} + +int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; } + +const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) { + return s->file; +} + +int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) { + return s->method_count; +} + +const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) { + return (i < 0 || i >= s->method_count) ? NULL + : _upb_MethodDef_At(s->methods, i); +} + +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name) { + return upb_ServiceDef_FindMethodByNameWithSize(s, name, strlen(name)); +} + +const upb_MethodDef* upb_ServiceDef_FindMethodByNameWithSize( + const upb_ServiceDef* s, const char* name, size_t len) { + upb_value val; + + if (!upb_strtable_lookup2(&s->ntom, name, len, &val)) { + return NULL; + } + + return _upb_DefType_Unpack(val, UPB_DEFTYPE_METHOD); +} + +static void create_service(upb_DefBuilder* ctx, + const google_protobuf_ServiceDescriptorProto* svc_proto, + const google_protobuf_FeatureSet* parent_features, + upb_ServiceDef* s) { + UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, + svc_proto); + s->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, google_protobuf_ServiceOptions_features(s->opts)); + + // Must happen before _upb_DefBuilder_Add() + s->file = _upb_DefBuilder_File(ctx); + + upb_StringView name = google_protobuf_ServiceDescriptorProto_name(svc_proto); + const char* package = _upb_FileDef_RawPackage(s->file); + s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name); + _upb_DefBuilder_Add(ctx, s->full_name, + _upb_DefType_Pack(s, UPB_DEFTYPE_SERVICE)); + + size_t n; + const google_protobuf_MethodDescriptorProto* const* methods = + google_protobuf_ServiceDescriptorProto_method(svc_proto, &n); + s->method_count = n; + bool ok = upb_strtable_init(&s->ntom, n, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); + s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s); +} + +upb_ServiceDef* _upb_ServiceDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_ServiceDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features) { + _upb_DefType_CheckPadding(sizeof(upb_ServiceDef)); + + upb_ServiceDef* s = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_ServiceDef, n); + for (int i = 0; i < n; i++) { + create_service(ctx, protos[i], parent_features, &s[i]); + s[i].index = i; + } + return s; +} + +void _upb_ServiceDef_InsertMethod(upb_DefBuilder* ctx, upb_ServiceDef* s, + const upb_MethodDef* m) { + const char* shortname = upb_MethodDef_Name(m); + const size_t shortnamelen = strlen(shortname); + upb_value existing_v; + if (upb_strtable_lookup(&s->ntom, shortname, &existing_v)) { + _upb_DefBuilder_Errf(ctx, "duplicate method name (%s)", shortname); + } + const upb_value method_v = _upb_DefType_Pack(m, UPB_DEFTYPE_METHOD); + bool ok = upb_strtable_insert(&s->ntom, shortname, shortnamelen, method_v, + ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); +} + + +#include <inttypes.h> +#include <math.h> +#include <setjmp.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +typedef struct { + upb_Arena* arena; + jmp_buf err; +} upb_ToProto_Context; + +#define CHK_OOM(val) \ + if (!(val)) UPB_LONGJMP(ctx->err, 1); + +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define SET_OPTIONS(proto, desc_type, options_type, src, extreg) \ + { \ + size_t size; \ + /* MEM: could use a temporary arena here instead. */ \ + char* pb = google_protobuf_##options_type##_serialize(src, ctx->arena, &size); \ + CHK_OOM(pb); \ + google_protobuf_##options_type* dst = \ + google_protobuf_##options_type##_parse_ex(pb, size, extreg, 0, ctx->arena); \ + CHK_OOM(dst); \ + google_protobuf_##desc_type##_set_options(proto, dst); \ + } + +static upb_StringView strviewdup2(upb_ToProto_Context* ctx, + upb_StringView str) { + char* p = upb_Arena_Malloc(ctx->arena, str.size); + CHK_OOM(p); + memcpy(p, str.data, str.size); + return (upb_StringView){.data = p, .size = str.size}; +} + +static upb_StringView strviewdup(upb_ToProto_Context* ctx, const char* s) { + return strviewdup2(ctx, (upb_StringView){.data = s, .size = strlen(s)}); +} + +static upb_StringView qual_dup(upb_ToProto_Context* ctx, const char* s) { + size_t n = strlen(s); + char* p = upb_Arena_Malloc(ctx->arena, n + 1); + CHK_OOM(p); + p[0] = '.'; + memcpy(p + 1, s, n); + return (upb_StringView){.data = p, .size = n + 1}; +} + +UPB_PRINTF(2, 3) +static upb_StringView printf_dup(upb_ToProto_Context* ctx, const char* fmt, + ...) { + const size_t max = 32; + char* p = upb_Arena_Malloc(ctx->arena, max); + CHK_OOM(p); + va_list args; + va_start(args, fmt); + size_t n = _upb_vsnprintf(p, max, fmt, args); + va_end(args); + UPB_ASSERT(n < max); + return (upb_StringView){.data = p, .size = n}; +} + +static bool upb_isprint(char ch) { return ch >= 0x20 && ch <= 0x7f; } + +static int special_escape(char ch) { + switch (ch) { + // This is the same set of special escapes recognized by + // absl::CEscape(). + case '\n': + return 'n'; + case '\r': + return 'r'; + case '\t': + return 't'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '"': + return '"'; + default: + return -1; + } +} + +static upb_StringView default_bytes(upb_ToProto_Context* ctx, + upb_StringView val) { + size_t n = 0; + for (size_t i = 0; i < val.size; i++) { + char ch = val.data[i]; + if (special_escape(ch) >= 0) + n += 2; // '\C' + else if (upb_isprint(ch)) + n += 1; + else + n += 4; // '\123' + } + char* p = upb_Arena_Malloc(ctx->arena, n); + CHK_OOM(p); + char* dst = p; + const char* src = val.data; + const char* end = src + val.size; + while (src < end) { + unsigned char ch = *src++; + if (special_escape(ch) >= 0) { + *dst++ = '\\'; + *dst++ = (char)special_escape(ch); + } else if (upb_isprint(ch)) { + *dst++ = ch; + } else { + *dst++ = '\\'; + *dst++ = '0' + (ch >> 6); + *dst++ = '0' + ((ch >> 3) & 0x7); + *dst++ = '0' + (ch & 0x7); + } + } + return (upb_StringView){.data = p, .size = n}; +} + +static upb_StringView default_string(upb_ToProto_Context* ctx, + const upb_FieldDef* f) { + upb_MessageValue d = upb_FieldDef_Default(f); + upb_CType type = upb_FieldDef_CType(f); + + if (type == kUpb_CType_Float || type == kUpb_CType_Double) { + double val = type == kUpb_CType_Float ? d.float_val : d.double_val; + if (val == INFINITY) { + return strviewdup(ctx, "inf"); + } else if (val == -INFINITY) { + return strviewdup(ctx, "-inf"); + } else if (val != val) { + return strviewdup(ctx, "nan"); + } + } + + switch (upb_FieldDef_CType(f)) { + case kUpb_CType_Bool: + return strviewdup(ctx, d.bool_val ? "true" : "false"); + case kUpb_CType_Enum: { + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); + const upb_EnumValueDef* ev = + upb_EnumDef_FindValueByNumber(e, d.int32_val); + return strviewdup(ctx, upb_EnumValueDef_Name(ev)); + } + case kUpb_CType_Int64: + return printf_dup(ctx, "%" PRId64, d.int64_val); + case kUpb_CType_UInt64: + return printf_dup(ctx, "%" PRIu64, d.uint64_val); + case kUpb_CType_Int32: + return printf_dup(ctx, "%" PRId32, d.int32_val); + case kUpb_CType_UInt32: + return printf_dup(ctx, "%" PRIu32, d.uint32_val); + case kUpb_CType_Float: + return printf_dup(ctx, "%.9g", d.float_val); + case kUpb_CType_Double: + return printf_dup(ctx, "%.17g", d.double_val); + case kUpb_CType_String: + return strviewdup2(ctx, d.str_val); + case kUpb_CType_Bytes: + return default_bytes(ctx, d.str_val); + default: + UPB_UNREACHABLE(); + } +} + +static google_protobuf_DescriptorProto_ReservedRange* resrange_toproto( + upb_ToProto_Context* ctx, const upb_MessageReservedRange* r) { + google_protobuf_DescriptorProto_ReservedRange* proto = + google_protobuf_DescriptorProto_ReservedRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_ReservedRange_set_start( + proto, upb_MessageReservedRange_Start(r)); + google_protobuf_DescriptorProto_ReservedRange_set_end(proto, + upb_MessageReservedRange_End(r)); + + return proto; +} + +static google_protobuf_EnumDescriptorProto_EnumReservedRange* enumresrange_toproto( + upb_ToProto_Context* ctx, const upb_EnumReservedRange* r) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* proto = + google_protobuf_EnumDescriptorProto_EnumReservedRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start( + proto, upb_EnumReservedRange_Start(r)); + google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end( + proto, upb_EnumReservedRange_End(r)); + + return proto; +} + +static google_protobuf_FieldDescriptorProto* fielddef_toproto(upb_ToProto_Context* ctx, + const upb_FieldDef* f) { + google_protobuf_FieldDescriptorProto* proto = + google_protobuf_FieldDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_FieldDescriptorProto_set_name(proto, + strviewdup(ctx, upb_FieldDef_Name(f))); + google_protobuf_FieldDescriptorProto_set_number(proto, upb_FieldDef_Number(f)); + + if (upb_FieldDef_IsRequired(f) && + upb_FileDef_Edition(upb_FieldDef_File(f)) >= google_protobuf_EDITION_2023) { + google_protobuf_FieldDescriptorProto_set_label( + proto, google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL); + } else { + google_protobuf_FieldDescriptorProto_set_label(proto, upb_FieldDef_Label(f)); + } + if (upb_FieldDef_Type(f) == kUpb_FieldType_Group && + upb_FileDef_Edition(upb_FieldDef_File(f)) >= google_protobuf_EDITION_2023) { + google_protobuf_FieldDescriptorProto_set_type(proto, kUpb_FieldType_Message); + } else { + google_protobuf_FieldDescriptorProto_set_type(proto, upb_FieldDef_Type(f)); + } + + if (upb_FieldDef_HasJsonName(f)) { + google_protobuf_FieldDescriptorProto_set_json_name( + proto, strviewdup(ctx, upb_FieldDef_JsonName(f))); + } + + if (upb_FieldDef_IsSubMessage(f)) { + google_protobuf_FieldDescriptorProto_set_type_name( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_MessageSubDef(f)))); + } else if (upb_FieldDef_CType(f) == kUpb_CType_Enum) { + google_protobuf_FieldDescriptorProto_set_type_name( + proto, qual_dup(ctx, upb_EnumDef_FullName(upb_FieldDef_EnumSubDef(f)))); + } + + if (upb_FieldDef_IsExtension(f)) { + google_protobuf_FieldDescriptorProto_set_extendee( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_FieldDef_ContainingType(f)))); + } + + if (upb_FieldDef_HasDefault(f)) { + google_protobuf_FieldDescriptorProto_set_default_value(proto, + default_string(ctx, f)); + } + + const upb_OneofDef* o = upb_FieldDef_ContainingOneof(f); + if (o) { + google_protobuf_FieldDescriptorProto_set_oneof_index(proto, upb_OneofDef_Index(o)); + } + + if (_upb_FieldDef_IsProto3Optional(f)) { + google_protobuf_FieldDescriptorProto_set_proto3_optional(proto, true); + } + + if (upb_FieldDef_HasOptions(f)) { + SET_OPTIONS(proto, FieldDescriptorProto, FieldOptions, + upb_FieldDef_Options(f), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_FieldDef_File(f)))); + } + + return proto; +} + +static google_protobuf_OneofDescriptorProto* oneofdef_toproto(upb_ToProto_Context* ctx, + const upb_OneofDef* o) { + google_protobuf_OneofDescriptorProto* proto = + google_protobuf_OneofDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_OneofDescriptorProto_set_name(proto, + strviewdup(ctx, upb_OneofDef_Name(o))); + + if (upb_OneofDef_HasOptions(o)) { + SET_OPTIONS(proto, OneofDescriptorProto, OneofOptions, + upb_OneofDef_Options(o), + _upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool( + upb_MessageDef_File(upb_OneofDef_ContainingType(o))))); + } + + return proto; +} + +static google_protobuf_EnumValueDescriptorProto* enumvaldef_toproto( + upb_ToProto_Context* ctx, const upb_EnumValueDef* e) { + google_protobuf_EnumValueDescriptorProto* proto = + google_protobuf_EnumValueDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumValueDescriptorProto_set_name( + proto, strviewdup(ctx, upb_EnumValueDef_Name(e))); + google_protobuf_EnumValueDescriptorProto_set_number(proto, upb_EnumValueDef_Number(e)); + + if (upb_EnumValueDef_HasOptions(e)) { + SET_OPTIONS(proto, EnumValueDescriptorProto, EnumValueOptions, + upb_EnumValueDef_Options(e), + _upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool( + upb_EnumDef_File(upb_EnumValueDef_Enum(e))))); + } + + return proto; +} + +static google_protobuf_EnumDescriptorProto* enumdef_toproto(upb_ToProto_Context* ctx, + const upb_EnumDef* e) { + google_protobuf_EnumDescriptorProto* proto = + google_protobuf_EnumDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_EnumDescriptorProto_set_name(proto, + strviewdup(ctx, upb_EnumDef_Name(e))); + + int n = upb_EnumDef_ValueCount(e); + google_protobuf_EnumValueDescriptorProto** vals = + google_protobuf_EnumDescriptorProto_resize_value(proto, n, ctx->arena); + CHK_OOM(vals); + for (int i = 0; i < n; i++) { + vals[i] = enumvaldef_toproto(ctx, upb_EnumDef_Value(e, i)); + } + + n = upb_EnumDef_ReservedRangeCount(e); + google_protobuf_EnumDescriptorProto_EnumReservedRange** res_ranges = + google_protobuf_EnumDescriptorProto_resize_reserved_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_ranges[i] = enumresrange_toproto(ctx, upb_EnumDef_ReservedRange(e, i)); + } + + n = upb_EnumDef_ReservedNameCount(e); + upb_StringView* res_names = + google_protobuf_EnumDescriptorProto_resize_reserved_name(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_names[i] = upb_EnumDef_ReservedName(e, i); + } + + if (upb_EnumDef_HasOptions(e)) { + SET_OPTIONS(proto, EnumDescriptorProto, EnumOptions, upb_EnumDef_Options(e), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_EnumDef_File(e)))); + } + + google_protobuf_SymbolVisibility visibility = upb_EnumDef_Visibility(e); + if (visibility != google_protobuf_VISIBILITY_UNSET) { + google_protobuf_EnumDescriptorProto_set_visibility(proto, visibility); + } + + return proto; +} + +static google_protobuf_DescriptorProto_ExtensionRange* extrange_toproto( + upb_ToProto_Context* ctx, const upb_MessageDef* m, + const upb_ExtensionRange* e) { + google_protobuf_DescriptorProto_ExtensionRange* proto = + google_protobuf_DescriptorProto_ExtensionRange_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_ExtensionRange_set_start(proto, + upb_ExtensionRange_Start(e)); + google_protobuf_DescriptorProto_ExtensionRange_set_end(proto, + upb_ExtensionRange_End(e)); + + if (upb_ExtensionRange_HasOptions(e)) { + SET_OPTIONS(proto, DescriptorProto_ExtensionRange, ExtensionRangeOptions, + upb_ExtensionRange_Options(e), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_MessageDef_File(m)))); + } + + return proto; +} + +static google_protobuf_DescriptorProto* msgdef_toproto(upb_ToProto_Context* ctx, + const upb_MessageDef* m) { + google_protobuf_DescriptorProto* proto = google_protobuf_DescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_DescriptorProto_set_name(proto, + strviewdup(ctx, upb_MessageDef_Name(m))); + + int n; + + n = upb_MessageDef_FieldCount(m); + google_protobuf_FieldDescriptorProto** fields = + google_protobuf_DescriptorProto_resize_field(proto, n, ctx->arena); + CHK_OOM(fields); + for (int i = 0; i < n; i++) { + fields[i] = fielddef_toproto(ctx, upb_MessageDef_Field(m, i)); + } + + n = upb_MessageDef_OneofCount(m); + google_protobuf_OneofDescriptorProto** oneofs = + google_protobuf_DescriptorProto_resize_oneof_decl(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + oneofs[i] = oneofdef_toproto(ctx, upb_MessageDef_Oneof(m, i)); + } + + n = upb_MessageDef_NestedMessageCount(m); + google_protobuf_DescriptorProto** nested_msgs = + google_protobuf_DescriptorProto_resize_nested_type(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_msgs[i] = msgdef_toproto(ctx, upb_MessageDef_NestedMessage(m, i)); + } + + n = upb_MessageDef_NestedEnumCount(m); + google_protobuf_EnumDescriptorProto** nested_enums = + google_protobuf_DescriptorProto_resize_enum_type(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_enums[i] = enumdef_toproto(ctx, upb_MessageDef_NestedEnum(m, i)); + } + + n = upb_MessageDef_NestedExtensionCount(m); + google_protobuf_FieldDescriptorProto** nested_exts = + google_protobuf_DescriptorProto_resize_extension(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + nested_exts[i] = + fielddef_toproto(ctx, upb_MessageDef_NestedExtension(m, i)); + } + + n = upb_MessageDef_ExtensionRangeCount(m); + google_protobuf_DescriptorProto_ExtensionRange** ext_ranges = + google_protobuf_DescriptorProto_resize_extension_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + ext_ranges[i] = + extrange_toproto(ctx, m, upb_MessageDef_ExtensionRange(m, i)); + } + + n = upb_MessageDef_ReservedRangeCount(m); + google_protobuf_DescriptorProto_ReservedRange** res_ranges = + google_protobuf_DescriptorProto_resize_reserved_range(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_ranges[i] = resrange_toproto(ctx, upb_MessageDef_ReservedRange(m, i)); + } + + n = upb_MessageDef_ReservedNameCount(m); + upb_StringView* res_names = + google_protobuf_DescriptorProto_resize_reserved_name(proto, n, ctx->arena); + for (int i = 0; i < n; i++) { + res_names[i] = upb_MessageDef_ReservedName(m, i); + } + + if (upb_MessageDef_HasOptions(m)) { + SET_OPTIONS(proto, DescriptorProto, MessageOptions, + upb_MessageDef_Options(m), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_MessageDef_File(m)))); + } + + google_protobuf_SymbolVisibility visibility = upb_MessageDef_Visibility(m); + if (visibility != google_protobuf_VISIBILITY_UNSET) { + google_protobuf_DescriptorProto_set_visibility(proto, visibility); + } + + return proto; +} + +static google_protobuf_MethodDescriptorProto* methoddef_toproto(upb_ToProto_Context* ctx, + const upb_MethodDef* m) { + google_protobuf_MethodDescriptorProto* proto = + google_protobuf_MethodDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_MethodDescriptorProto_set_name(proto, + strviewdup(ctx, upb_MethodDef_Name(m))); + + google_protobuf_MethodDescriptorProto_set_input_type( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_InputType(m)))); + google_protobuf_MethodDescriptorProto_set_output_type( + proto, + qual_dup(ctx, upb_MessageDef_FullName(upb_MethodDef_OutputType(m)))); + + if (upb_MethodDef_ClientStreaming(m)) { + google_protobuf_MethodDescriptorProto_set_client_streaming(proto, true); + } + + if (upb_MethodDef_ServerStreaming(m)) { + google_protobuf_MethodDescriptorProto_set_server_streaming(proto, true); + } + + if (upb_MethodDef_HasOptions(m)) { + SET_OPTIONS( + proto, MethodDescriptorProto, MethodOptions, upb_MethodDef_Options(m), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_ServiceDef_File(upb_MethodDef_Service(m))))); + } + + return proto; +} + +static google_protobuf_ServiceDescriptorProto* servicedef_toproto( + upb_ToProto_Context* ctx, const upb_ServiceDef* s) { + google_protobuf_ServiceDescriptorProto* proto = + google_protobuf_ServiceDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_ServiceDescriptorProto_set_name( + proto, strviewdup(ctx, upb_ServiceDef_Name(s))); + + size_t n = upb_ServiceDef_MethodCount(s); + google_protobuf_MethodDescriptorProto** methods = + google_protobuf_ServiceDescriptorProto_resize_method(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + methods[i] = methoddef_toproto(ctx, upb_ServiceDef_Method(s, i)); + } + + if (upb_ServiceDef_HasOptions(s)) { + SET_OPTIONS(proto, ServiceDescriptorProto, ServiceOptions, + upb_ServiceDef_Options(s), + _upb_DefPool_GeneratedExtensionRegistry( + upb_FileDef_Pool(upb_ServiceDef_File(s)))); + } + + return proto; +} + +static google_protobuf_FileDescriptorProto* filedef_toproto(upb_ToProto_Context* ctx, + const upb_FileDef* f) { + google_protobuf_FileDescriptorProto* proto = + google_protobuf_FileDescriptorProto_new(ctx->arena); + CHK_OOM(proto); + + google_protobuf_FileDescriptorProto_set_name(proto, + strviewdup(ctx, upb_FileDef_Name(f))); + + const char* package = upb_FileDef_Package(f); + if (package) { + size_t n = strlen(package); + if (n) { + google_protobuf_FileDescriptorProto_set_package(proto, strviewdup(ctx, package)); + } + } + + google_protobuf_Edition edition = upb_FileDef_Edition(f); + + switch (edition) { + case google_protobuf_EDITION_PROTO2: + // We could set syntax to "proto2", but C++ omits it completely, which is + // equivalent. + break; + case google_protobuf_EDITION_PROTO3: + google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "proto3")); + break; + default: + google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "editions")); + google_protobuf_FileDescriptorProto_set_edition(proto, edition); + break; + } + + size_t n; + n = upb_FileDef_DependencyCount(f); + upb_StringView* deps = + google_protobuf_FileDescriptorProto_resize_dependency(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + deps[i] = strviewdup(ctx, upb_FileDef_Name(upb_FileDef_Dependency(f, i))); + } + + n = upb_FileDef_PublicDependencyCount(f); + int32_t* public_deps = + google_protobuf_FileDescriptorProto_resize_public_dependency(proto, n, ctx->arena); + const int32_t* public_dep_nums = _upb_FileDef_PublicDependencyIndexes(f); + if (n) memcpy(public_deps, public_dep_nums, n * sizeof(int32_t)); + + n = upb_FileDef_WeakDependencyCount(f); + int32_t* weak_deps = + google_protobuf_FileDescriptorProto_resize_weak_dependency(proto, n, ctx->arena); + const int32_t* weak_dep_nums = _upb_FileDef_WeakDependencyIndexes(f); + if (n) memcpy(weak_deps, weak_dep_nums, n * sizeof(int32_t)); + + n = upb_FileDef_TopLevelMessageCount(f); + google_protobuf_DescriptorProto** msgs = + google_protobuf_FileDescriptorProto_resize_message_type(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + msgs[i] = msgdef_toproto(ctx, upb_FileDef_TopLevelMessage(f, i)); + } + + n = upb_FileDef_TopLevelEnumCount(f); + google_protobuf_EnumDescriptorProto** enums = + google_protobuf_FileDescriptorProto_resize_enum_type(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + enums[i] = enumdef_toproto(ctx, upb_FileDef_TopLevelEnum(f, i)); + } + + n = upb_FileDef_ServiceCount(f); + google_protobuf_ServiceDescriptorProto** services = + google_protobuf_FileDescriptorProto_resize_service(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + services[i] = servicedef_toproto(ctx, upb_FileDef_Service(f, i)); + } + + n = upb_FileDef_TopLevelExtensionCount(f); + google_protobuf_FieldDescriptorProto** exts = + google_protobuf_FileDescriptorProto_resize_extension(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + exts[i] = fielddef_toproto(ctx, upb_FileDef_TopLevelExtension(f, i)); + } + + if (upb_FileDef_HasOptions(f)) { + SET_OPTIONS(proto, FileDescriptorProto, FileOptions, upb_FileDef_Options(f), + _upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool(f))); + } + + return proto; +} + +static google_protobuf_DescriptorProto* upb_ToProto_ConvertMessageDef( + upb_ToProto_Context* const ctx, const upb_MessageDef* const m) { + if (UPB_SETJMP(ctx->err)) return NULL; + return msgdef_toproto(ctx, m); +} + +google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertMessageDef(&ctx, m); +} + +google_protobuf_EnumDescriptorProto* upb_ToProto_ConvertEnumDef( + upb_ToProto_Context* const ctx, const upb_EnumDef* const e) { + if (UPB_SETJMP(ctx->err)) return NULL; + return enumdef_toproto(ctx, e); +} + +google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertEnumDef(&ctx, e); +} + +google_protobuf_EnumValueDescriptorProto* upb_ToProto_ConvertEnumValueDef( + upb_ToProto_Context* const ctx, const upb_EnumValueDef* e) { + if (UPB_SETJMP(ctx->err)) return NULL; + return enumvaldef_toproto(ctx, e); +} + +google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto( + const upb_EnumValueDef* e, upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertEnumValueDef(&ctx, e); +} + +google_protobuf_FieldDescriptorProto* upb_ToProto_ConvertFieldDef( + upb_ToProto_Context* const ctx, const upb_FieldDef* f) { + if (UPB_SETJMP(ctx->err)) return NULL; + return fielddef_toproto(ctx, f); +} + +google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto(const upb_FieldDef* f, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertFieldDef(&ctx, f); +} + +google_protobuf_OneofDescriptorProto* upb_ToProto_ConvertOneofDef( + upb_ToProto_Context* const ctx, const upb_OneofDef* o) { + if (UPB_SETJMP(ctx->err)) return NULL; + return oneofdef_toproto(ctx, o); +} + +google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto(const upb_OneofDef* o, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertOneofDef(&ctx, o); +} + +google_protobuf_FileDescriptorProto* upb_ToProto_ConvertFileDef( + upb_ToProto_Context* const ctx, const upb_FileDef* const f) { + if (UPB_SETJMP(ctx->err)) return NULL; + return filedef_toproto(ctx, f); +} + +google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertFileDef(&ctx, f); +} + +google_protobuf_MethodDescriptorProto* upb_ToProto_ConvertMethodDef( + upb_ToProto_Context* const ctx, const upb_MethodDef* m) { + if (UPB_SETJMP(ctx->err)) return NULL; + return methoddef_toproto(ctx, m); +} + +google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto( + const upb_MethodDef* const m, upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertMethodDef(&ctx, m); +} + +google_protobuf_ServiceDescriptorProto* upb_ToProto_ConvertServiceDef( + upb_ToProto_Context* const ctx, const upb_ServiceDef* const s) { + if (UPB_SETJMP(ctx->err)) return NULL; + return servicedef_toproto(ctx, s); +} + +google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto(const upb_ServiceDef* s, + upb_Arena* a) { + upb_ToProto_Context ctx = {a}; + return upb_ToProto_ConvertServiceDef(&ctx, s); +} + + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Our awkward dance for including fasttable only when it is enabled. +#if UPB_FASTTABLE +#define UPB_INCLUDE_FAST_DECODE +#endif + +#ifdef UPB_INCLUDE_FAST_DECODE +#endif + +#undef UPB_INCLUDE_FAST_DECODE + +// Must be last. + +// A few fake field types for our tables. +enum { + kUpb_FakeFieldType_FieldNotFound = 0, + kUpb_FakeFieldType_MessageSetItem = 19, +}; + +// DecodeOp: an action to be performed for a wire-type/field-type combination. +enum { + // Special ops: we don't write data to regular fields for these. + kUpb_DecodeOp_UnknownField = -1, + kUpb_DecodeOp_MessageSetItem = -2, + + // Scalar-only ops. + kUpb_DecodeOp_Scalar1Byte = 0, + kUpb_DecodeOp_Scalar4Byte = 2, + kUpb_DecodeOp_Scalar8Byte = 3, + + // Scalar/repeated ops. + kUpb_DecodeOp_String = 4, + kUpb_DecodeOp_Bytes = 5, + kUpb_DecodeOp_SubMessage = 6, + + // Repeated-only ops (also see macros below). + kUpb_DecodeOp_PackedEnum = 13, +}; + +// For packed fields it is helpful to be able to recover the lg2 of the data +// size from the op. +#define OP_FIXPCK_LG2(n) (n + 5) /* n in [2, 3] => op in [7, 8] */ +#define OP_VARPCK_LG2(n) (n + 9) /* n in [0, 2, 3] => op in [9, 11, 12] */ + +typedef union { + bool bool_val; + uint32_t uint32_val; + uint64_t uint64_val; + uint32_t size; +} wireval; + +static void _upb_Decoder_AssumeEpsHasErrorHandler(upb_Decoder* d) { + UPB_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(&d->input)); +} + +#define EPS(d) (_upb_Decoder_AssumeEpsHasErrorHandler(d), &(d)->input) + +static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) { + bool need_realloc = + arr->UPB_PRIVATE(capacity) - arr->UPB_PRIVATE(size) < elem; + if (need_realloc && !UPB_PRIVATE(_upb_Array_Realloc)( + arr, arr->UPB_PRIVATE(size) + elem, &d->arena)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + return need_realloc; +} + +typedef struct { + const char* ptr; + uint64_t val; +} _upb_DecodeLongVarintReturn; + +// This is identical to _upb_Decoder_DecodeTag() except that the maximum value +// is INT32_MAX instead of UINT32_MAX. +UPB_FORCEINLINE +const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr, + uint32_t* size) { + int sz; + ptr = upb_WireReader_ReadSize(ptr, &sz, EPS(d)); + *size = sz; + return ptr; +} + +static void _upb_Decoder_MungeInt32(wireval* val) { + if (!upb_IsLittleEndian()) { + /* The next stage will memcpy(dst, &val, 4) */ + val->uint32_val = val->uint64_val; + } +} + +static void _upb_Decoder_Munge(const upb_MiniTableField* field, wireval* val) { + switch (field->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Bool: + val->bool_val = val->uint64_val != 0; + break; + case kUpb_FieldType_SInt32: { + uint32_t n = val->uint64_val; + val->uint32_val = (n >> 1) ^ -(int32_t)(n & 1); + break; + } + case kUpb_FieldType_SInt64: { + uint64_t n = val->uint64_val; + val->uint64_val = (n >> 1) ^ -(int64_t)(n & 1); + break; + } + case kUpb_FieldType_Int32: + case kUpb_FieldType_UInt32: + _upb_Decoder_MungeInt32(val); + break; + case kUpb_FieldType_Enum: + UPB_UNREACHABLE(); + } +} + +static upb_Message* _upb_Decoder_NewSubMessage2(upb_Decoder* d, + const upb_MiniTable* subl, + const upb_MiniTableField* field, + upb_Message** target) { + UPB_ASSERT(subl); + upb_Message* msg = _upb_Message_New(subl, &d->arena); + if (!msg) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + + *target = msg; + return msg; +} + +static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, + const upb_MiniTableField* field, + upb_Message** target) { + const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field); + return _upb_Decoder_NewSubMessage2(d, subl, field, target); +} + +static const char* _upb_Decoder_ReadString2(upb_Decoder* d, const char* ptr, + int size, upb_StringView* str, + bool validate_utf8) { + if (!_upb_Decoder_ReadString(d, &ptr, size, str, validate_utf8)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_RecurseSubMessage(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable* subl, + uint32_t expected_end_group) { + if (--d->depth < 0) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_MaxDepthExceeded); + } + ptr = _upb_Decoder_DecodeMessage(d, ptr, submsg, subl); + d->depth++; + if (d->end_group != expected_end_group) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeSubMessage(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTableField* field, + size_t size) { + ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size); + const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field); + UPB_ASSERT(subl); + ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP); + upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta); + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeGroup(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTable* subl, + uint32_t number) { + if (upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, number); + d->end_group = DECODE_NOGROUP; + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeKnownGroup(upb_Decoder* d, const char* ptr, + upb_Message* submsg, + const upb_MiniTableField* field) { + const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field); + UPB_ASSERT(subl); + return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, + field->UPB_PRIVATE(number)); +} + +#define kUpb_Decoder_EncodeVarint32MaxSize 5 +static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +UPB_FORCEINLINE +void _upb_Decoder_AddEnumValueToUnknown(upb_Decoder* d, upb_Message* msg, + const upb_MiniTableField* field, + wireval* val) { + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, + // so we just re-encode the tag and value here. + const uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; + upb_Message* unknown_msg = + field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension ? d->original_msg + : msg; + char buf[2 * kUpb_Decoder_EncodeVarint32MaxSize]; + char* end = buf; + end = upb_Decoder_EncodeVarint32(tag, end); + end = upb_Decoder_EncodeVarint32(val->uint64_val, end); + + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(unknown_msg, buf, end - buf, + &d->arena, kUpb_AddUnknown_Copy)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFixedPacked(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTableField* field, + int lg2) { + upb_StringView sv; + ptr = upb_EpsCopyInputStream_ReadStringEphemeral(&d->input, ptr, val->size, + &sv); + if (!ptr) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + int mask = (1 << lg2) - 1; + if (UPB_UNLIKELY((val->size & mask) != 0 || ptr == NULL)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + size_t count = val->size >> lg2; + if (count == 0) return ptr; + _upb_Decoder_Reserve(d, arr, count); + void* mem = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << lg2, void); + arr->UPB_PRIVATE(size) += count; + if (upb_IsLittleEndian()) { + memcpy(mem, sv.data, sv.size); + } else { + const char* src = sv.data; + const char* src_end = src + sv.size; + char* dst = mem; + if (lg2 == 2) { + for (; src < src_end; src += 4, dst += 4) { + uint32_t x; + memcpy(&x, src, 4); + x = upb_BigEndian32(x); + memcpy(dst, &x, 4); + } + } else { + UPB_ASSERT(lg2 == 3); + for (; src < src_end; src += 8, dst += 8) { + uint64_t x; + memcpy(&x, src, 8); + x = upb_BigEndian64(x); + memcpy(dst, &x, 8); + } + } + } + + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeVarintPacked(upb_Decoder* d, const char* ptr, + upb_Array* arr, wireval* val, + const upb_MiniTableField* field, + int lg2) { + int scale = 1 << lg2; + ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); + char* out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << lg2, void); + while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + wireval elem; + ptr = upb_WireReader_ReadVarint(ptr, &elem.uint64_val, EPS(d)); + _upb_Decoder_Munge(field, &elem); + if (_upb_Decoder_Reserve(d, arr, 1)) { + out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << lg2, void); + } + arr->UPB_PRIVATE(size)++; + memcpy(out, &elem, scale); + out += scale; + } + upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta); + return ptr; +} + +UPB_NOINLINE +static const char* _upb_Decoder_DecodeEnumPacked( + upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr, + const upb_MiniTableField* field, wireval* val) { + const upb_MiniTableEnum* e = upb_MiniTable_GetSubEnumTable(field); + ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); + char* out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) * 4, void); + while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + wireval elem; + ptr = upb_WireReader_ReadVarint(ptr, &elem.uint64_val, EPS(d)); + if (!upb_MiniTableEnum_CheckValue(e, elem.uint64_val)) { + _upb_Decoder_AddEnumValueToUnknown(d, msg, field, &elem); + continue; + } + if (_upb_Decoder_Reserve(d, arr, 1)) { + out = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) * 4, void); + } + arr->UPB_PRIVATE(size)++; + memcpy(out, &elem, 4); + out += 4; + } + upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta); + return ptr; +} + +static upb_Array* _upb_Decoder_CreateArray(upb_Decoder* d, + const upb_MiniTableField* field) { + const upb_FieldType field_type = field->UPB_PRIVATE(descriptortype); + const size_t lg2 = UPB_PRIVATE(_upb_FieldType_SizeLg2)(field_type); + upb_Array* ret = UPB_PRIVATE(_upb_Array_New)(&d->arena, 4, lg2); + if (!ret) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + return ret; +} + +static const char* _upb_Decoder_DecodeToArray(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTableField* field, + wireval* val, int op) { + upb_Array** arrp = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void); + upb_Array* arr = *arrp; + void* mem; + + if (arr) { + _upb_Decoder_Reserve(d, arr, 1); + } else { + arr = _upb_Decoder_CreateArray(d, field); + *arrp = arr; + } + + switch (op) { + case kUpb_DecodeOp_Scalar1Byte: + case kUpb_DecodeOp_Scalar4Byte: + case kUpb_DecodeOp_Scalar8Byte: + /* Append scalar value. */ + mem = UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) << op, void); + arr->UPB_PRIVATE(size)++; + memcpy(mem, val, 1 << op); + return ptr; + case kUpb_DecodeOp_String: { + /* Append string. */ + upb_StringView* str = (upb_StringView*)upb_Array_MutableDataPtr(arr) + + arr->UPB_PRIVATE(size); + ptr = _upb_Decoder_ReadString2(d, ptr, val->size, str, + /*validate_utf8=*/true); + arr->UPB_PRIVATE(size)++; + return ptr; + } + case kUpb_DecodeOp_Bytes: { + /* Append bytes. */ + upb_StringView* str = (upb_StringView*)upb_Array_MutableDataPtr(arr) + + arr->UPB_PRIVATE(size); + ptr = _upb_Decoder_ReadString2(d, ptr, val->size, str, + /*validate_utf8=*/false); + arr->UPB_PRIVATE(size)++; + return ptr; + } + case kUpb_DecodeOp_SubMessage: { + /* Append submessage / group. */ + upb_Message** target = + UPB_PTR_AT(upb_Array_MutableDataPtr(arr), + arr->UPB_PRIVATE(size) * sizeof(void*), upb_Message*); + upb_Message* submsg = _upb_Decoder_NewSubMessage(d, field, target); + arr->UPB_PRIVATE(size)++; + if (UPB_UNLIKELY(field->UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group)) { + return _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, field); + } else { + return _upb_Decoder_DecodeSubMessage(d, ptr, submsg, field, val->size); + } + } + case OP_FIXPCK_LG2(2): + case OP_FIXPCK_LG2(3): + return _upb_Decoder_DecodeFixedPacked(d, ptr, arr, val, field, + op - OP_FIXPCK_LG2(0)); + case OP_VARPCK_LG2(0): + case OP_VARPCK_LG2(2): + case OP_VARPCK_LG2(3): + return _upb_Decoder_DecodeVarintPacked(d, ptr, arr, val, field, + op - OP_VARPCK_LG2(0)); + case kUpb_DecodeOp_PackedEnum: + return _upb_Decoder_DecodeEnumPacked(d, ptr, msg, arr, field, val); + default: + UPB_UNREACHABLE(); + } +} + +static upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, + const upb_MiniTable* entry) { + // Maps descriptor type -> upb map size + static const uint8_t kSizeInMap[] = { + [0] = -1, // invalid descriptor type + [kUpb_FieldType_Double] = 8, + [kUpb_FieldType_Float] = 4, + [kUpb_FieldType_Int64] = 8, + [kUpb_FieldType_UInt64] = 8, + [kUpb_FieldType_Int32] = 4, + [kUpb_FieldType_Fixed64] = 8, + [kUpb_FieldType_Fixed32] = 4, + [kUpb_FieldType_Bool] = 1, + [kUpb_FieldType_String] = UPB_MAPTYPE_STRING, + [kUpb_FieldType_Group] = sizeof(void*), + [kUpb_FieldType_Message] = sizeof(void*), + [kUpb_FieldType_Bytes] = UPB_MAPTYPE_STRING, + [kUpb_FieldType_UInt32] = 4, + [kUpb_FieldType_Enum] = 4, + [kUpb_FieldType_SFixed32] = 4, + [kUpb_FieldType_SFixed64] = 8, + [kUpb_FieldType_SInt32] = 4, + [kUpb_FieldType_SInt64] = 8, + }; + + const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1]; + char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)]; + char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)]; + UPB_ASSERT(key_field->UPB_PRIVATE(offset) == offsetof(upb_MapEntry, k)); + UPB_ASSERT(val_field->UPB_PRIVATE(offset) == offsetof(upb_MapEntry, v)); + upb_Map* ret = _upb_Map_New(&d->arena, key_size, val_size); + if (!ret) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + return ret; +} + +UPB_NOINLINE static void _upb_Decoder_AddMapEntryUnknown( + upb_Decoder* d, upb_Message* msg, const upb_MiniTableField* field, + upb_Message* ent_msg, const upb_MiniTable* entry) { + char* buf; + size_t size; + upb_EncodeStatus status = + upb_Encode(ent_msg, entry, 0, &d->arena, &buf, &size); + if (status != kUpb_EncodeStatus_Ok) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + char delim_buf[2 * kUpb_Decoder_EncodeVarint32MaxSize]; + char* delim_end = delim_buf; + uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Delimited; + delim_end = upb_Decoder_EncodeVarint32(tag, delim_end); + delim_end = upb_Decoder_EncodeVarint32(size, delim_end); + upb_StringView unknown[] = { + {delim_buf, delim_end - delim_buf}, + {buf, size}, + }; + + if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 2)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } +} + +static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTableField* field, + wireval* val) { + upb_Map** map_p = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), upb_Map*); + upb_Map* map = *map_p; + upb_MapEntry ent; + UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message); + const upb_MiniTable* entry = upb_MiniTable_GetSubMessageTable(field); + + UPB_ASSERT(entry); + UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0])); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1])); + + if (!map) { + map = _upb_Decoder_CreateMap(d, entry); + *map_p = map; + } + + // Parse map entry. + memset(&ent, 0, sizeof(ent)); + + bool value_is_message = + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Message || + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group; + const upb_MiniTable* sub_table = + value_is_message + ? upb_MiniTable_GetSubMessageTable(&entry->UPB_PRIVATE(fields)[1]) + : NULL; + upb_Message* sub_msg = NULL; + + if (sub_table) { + // Create proactively to handle the case where it doesn't appear. + _upb_Decoder_NewSubMessage(d, &entry->UPB_PRIVATE(fields)[1], &sub_msg); + ent.v.val = upb_value_ptr(sub_msg); + } + + ptr = _upb_Decoder_DecodeSubMessage(d, ptr, &ent.message, field, val->size); + + if (sub_msg && sub_table->UPB_PRIVATE(required_count)) { + // If the map entry did not contain a value on the wire, `sub_msg` is an + // empty message; we must check if it is missing any required fields. If the + // value was present, this check is redundant but harmless. + _upb_Decoder_CheckRequired(d, ptr, sub_msg, sub_table); + } + + if (upb_Message_HasUnknown(&ent.message)) { + _upb_Decoder_AddMapEntryUnknown(d, msg, field, &ent.message, entry); + } else { + if (_upb_Map_Insert(map, &ent.k, map->key_size, &ent.v, map->val_size, + &d->arena) == kUpb_MapInsertStatus_OutOfMemory) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + } + return ptr; +} + +static const char* _upb_Decoder_DecodeToSubMessage( + upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTableField* field, wireval* val, int op) { + void* mem = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void); + int type = field->UPB_PRIVATE(descriptortype); + + // Set presence if necessary. + if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(field)) { + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, field); + } else if (upb_MiniTableField_IsInOneof(field)) { + // Oneof case + uint32_t* oneof_case = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field); + if (op == kUpb_DecodeOp_SubMessage && + *oneof_case != field->UPB_PRIVATE(number)) { + memset(mem, 0, sizeof(void*)); + } + *oneof_case = field->UPB_PRIVATE(number); + } + + // Store into message. + switch (op) { + case kUpb_DecodeOp_SubMessage: { + upb_Message** submsgp = mem; + upb_Message* submsg = *submsgp; + if (!submsg) submsg = _upb_Decoder_NewSubMessage(d, field, submsgp); + if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) { + ptr = _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, field); + } else { + ptr = _upb_Decoder_DecodeSubMessage(d, ptr, submsg, field, val->size); + } + break; + } + case kUpb_DecodeOp_String: + return _upb_Decoder_ReadString2(d, ptr, val->size, mem, + /*validate_utf8=*/true); + case kUpb_DecodeOp_Bytes: + return _upb_Decoder_ReadString2(d, ptr, val->size, mem, + /*validate_utf8=*/false); + case kUpb_DecodeOp_Scalar8Byte: + memcpy(mem, val, 8); + break; + case kUpb_DecodeOp_Scalar4Byte: + memcpy(mem, val, 4); + break; + case kUpb_DecodeOp_Scalar1Byte: + memcpy(mem, val, 1); + break; + default: + UPB_UNREACHABLE(); + } + + return ptr; +} + +enum { + kStartItemTag = ((kUpb_MsgSet_Item << 3) | kUpb_WireType_StartGroup), + kEndItemTag = ((kUpb_MsgSet_Item << 3) | kUpb_WireType_EndGroup), + kTypeIdTag = ((kUpb_MsgSet_TypeId << 3) | kUpb_WireType_Varint), + kMessageTag = ((kUpb_MsgSet_Message << 3) | kUpb_WireType_Delimited), +}; + +static void upb_Decoder_AddKnownMessageSetItem( + upb_Decoder* d, upb_Message* msg, const upb_MiniTableExtension* item_mt, + const char* data, uint32_t size) { + upb_Extension* ext = + UPB_PRIVATE(_upb_Message_GetOrCreateExtension)(msg, item_mt, &d->arena); + if (UPB_UNLIKELY(!ext)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + upb_Message** submsgp = (upb_Message**)&ext->data.msg_val; + upb_Message* submsg = _upb_Decoder_NewSubMessage2( + d, ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg), + &ext->ext->UPB_PRIVATE(field), submsgp); + // upb_Decode_LimitDepth() takes uint32_t, d->depth - 1 can not be negative. + if (d->depth <= 1) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_MaxDepthExceeded); + } + upb_DecodeStatus status = upb_Decode( + data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt), + d->extreg, upb_Decode_LimitDepth(d->options, d->depth - 1), &d->arena); + if (status != kUpb_DecodeStatus_Ok) { + upb_ErrorHandler_ThrowError(&d->err, status); + } +} + +static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d, + upb_Message* msg, + uint32_t type_id, + const char* message_data, + uint32_t message_size) { + char buf[6 * kUpb_Decoder_EncodeVarint32MaxSize]; + char* ptr = buf; + ptr = upb_Decoder_EncodeVarint32(kStartItemTag, ptr); + ptr = upb_Decoder_EncodeVarint32(kTypeIdTag, ptr); + ptr = upb_Decoder_EncodeVarint32(type_id, ptr); + ptr = upb_Decoder_EncodeVarint32(kMessageTag, ptr); + ptr = upb_Decoder_EncodeVarint32(message_size, ptr); + char* split = ptr; + + ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr); + char* end = ptr; + upb_StringView unknown[] = { + {buf, split - buf}, + {message_data, message_size}, + {split, end - split}, + }; + if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 3)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } +} + +static void upb_Decoder_AddMessageSetItem(upb_Decoder* d, upb_Message* msg, + const upb_MiniTable* t, + uint32_t type_id, const char* data, + uint32_t size) { + const upb_MiniTableExtension* item_mt = + upb_ExtensionRegistry_Lookup(d->extreg, t, type_id); + if (item_mt) { + upb_Decoder_AddKnownMessageSetItem(d, msg, item_mt, data, size); + } else { + upb_Decoder_AddUnknownMessageSetItem(d, msg, type_id, data, size); + } +} + +static const char* upb_Decoder_DecodeMessageSetItem( + upb_Decoder* d, const char* ptr, upb_Message* msg, + const upb_MiniTable* layout) { + uint32_t type_id = 0; + upb_StringView preserved = {NULL, 0}; + typedef enum { + kUpb_HaveId = 1 << 0, + kUpb_HavePayload = 1 << 1, + } StateMask; + StateMask state_mask = 0; + while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + uint32_t tag; + ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d)); + switch (tag) { + case kEndItemTag: + return ptr; + case kTypeIdTag: { + uint64_t tmp; + ptr = upb_WireReader_ReadVarint(ptr, &tmp, EPS(d)); + if (state_mask & kUpb_HaveId) break; // Ignore dup. + state_mask |= kUpb_HaveId; + type_id = tmp; + if (state_mask & kUpb_HavePayload) { + upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, preserved.data, + preserved.size); + } + break; + } + case kMessageTag: { + uint32_t size; + upb_StringView sv; + ptr = upb_Decoder_DecodeSize(d, ptr, &size); + ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(&d->input, ptr, size, + &sv); + if (!ptr) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + if (state_mask & kUpb_HavePayload) break; // Ignore dup. + state_mask |= kUpb_HavePayload; + if (state_mask & kUpb_HaveId) { + upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, sv.data, + sv.size); + } else { + // Out of order, we must preserve the payload. + preserved = sv; + } + break; + } + default: + // We do not preserve unexpected fields inside a message set item. + ptr = _upb_WireReader_SkipValue(ptr, tag, d->depth, &d->input); + break; + } + } + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); +} + +static upb_MiniTableField upb_Decoder_FieldNotFoundField = { + 0, 0, 0, 0, kUpb_FakeFieldType_FieldNotFound, 0}; + +UPB_NOINLINE const upb_MiniTableField* _upb_Decoder_FindExtensionField( + upb_Decoder* d, const upb_MiniTable* t, uint32_t field_number, int ext_mode, + uint32_t wire_type) { + // Treat a message set as an extendable message if it is a delimited field. + // This provides compatibility with encoders that are unaware of message + // sets and serialize them as normal extensions. + if (ext_mode == kUpb_ExtMode_Extendable || + (ext_mode == kUpb_ExtMode_IsMessageSet && + wire_type == kUpb_WireType_Delimited)) { + const upb_MiniTableExtension* ext = + upb_ExtensionRegistry_Lookup(d->extreg, t, field_number); + if (ext) return &ext->UPB_PRIVATE(field); + } else if (ext_mode == kUpb_ExtMode_IsMessageSet) { + if (field_number == kUpb_MsgSet_Item) { + static upb_MiniTableField item = { + 0, 0, 0, 0, kUpb_FakeFieldType_MessageSetItem, 0}; + return &item; + } + } + return &upb_Decoder_FieldNotFoundField; +} + +static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, + const upb_MiniTable* t, + uint32_t field_number, + uint32_t wire_type) { + UPB_ASSERT(t); + const upb_MiniTableField* field = + upb_MiniTable_FindFieldByNumber(t, field_number); + if (field) return field; + + if (d->extreg && t->UPB_PRIVATE(ext)) { + return _upb_Decoder_FindExtensionField(d, t, field_number, + t->UPB_PRIVATE(ext), wire_type); + } + + return &upb_Decoder_FieldNotFoundField; // Unknown field. +} + +static int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { + static const int8_t kVarintOps[] = { + [kUpb_FakeFieldType_FieldNotFound] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Double] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Float] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Int64] = kUpb_DecodeOp_Scalar8Byte, + [kUpb_FieldType_UInt64] = kUpb_DecodeOp_Scalar8Byte, + [kUpb_FieldType_Int32] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_Fixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Fixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Bool] = kUpb_DecodeOp_Scalar1Byte, + [kUpb_FieldType_String] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Group] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Message] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Bytes] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_UInt32] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_Enum] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_SFixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SFixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SInt32] = kUpb_DecodeOp_Scalar4Byte, + [kUpb_FieldType_SInt64] = kUpb_DecodeOp_Scalar8Byte, + [kUpb_FakeFieldType_MessageSetItem] = kUpb_DecodeOp_UnknownField, + }; + + return kVarintOps[field->UPB_PRIVATE(descriptortype)]; +} + +UPB_FORCEINLINE +void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, + const upb_MiniTableField* field, int* op) { + // If sub-message is not linked, treat as unknown. + if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension) return; + const upb_MiniTable* mt_sub = upb_MiniTable_GetSubMessageTable(field); + if (mt_sub != NULL) return; // Normal case, sub-message is linked. +#ifndef NDEBUG + const upb_MiniTableField* oneof = upb_MiniTable_GetOneof(mt, field); + if (oneof) { + // All other members of the oneof must be message fields that are also + // unlinked. + do { + UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message); + const upb_MiniTable* oneof_sub = upb_MiniTable_GetSubMessageTable(oneof); + UPB_ASSERT(!oneof_sub); + } while (upb_MiniTable_NextOneofField(mt, &oneof)); + } +#endif // NDEBUG + *op = kUpb_DecodeOp_UnknownField; +} + +UPB_FORCEINLINE +void _upb_Decoder_MaybeVerifyUtf8(upb_Decoder* d, + const upb_MiniTableField* field, int* op) { + UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes); + if (_upb_Decoder_FieldRequiresUtf8Validation(d, field)) { + *op = kUpb_DecodeOp_String; + } +} + +static int _upb_Decoder_GetDelimitedOp(upb_Decoder* d, const upb_MiniTable* mt, + const upb_MiniTableField* field) { + enum { kRepeatedBase = 19 }; + + static const int8_t kDelimitedOps[] = { + // For non-repeated field type. + [kUpb_FakeFieldType_FieldNotFound] = + kUpb_DecodeOp_UnknownField, // Field not found. + [kUpb_FieldType_Double] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Float] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Int64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_UInt64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Int32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Fixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Fixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Bool] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_String] = kUpb_DecodeOp_String, + [kUpb_FieldType_Group] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Message] = kUpb_DecodeOp_SubMessage, + [kUpb_FieldType_Bytes] = kUpb_DecodeOp_Bytes, + [kUpb_FieldType_UInt32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_Enum] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SFixed32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SFixed64] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SInt32] = kUpb_DecodeOp_UnknownField, + [kUpb_FieldType_SInt64] = kUpb_DecodeOp_UnknownField, + [kUpb_FakeFieldType_MessageSetItem] = kUpb_DecodeOp_SubMessage, + // For repeated field type. + [kRepeatedBase + kUpb_FieldType_Double] = OP_FIXPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_Float] = OP_FIXPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Int64] = OP_VARPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_UInt64] = OP_VARPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_Int32] = OP_VARPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Fixed64] = OP_FIXPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_Fixed32] = OP_FIXPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Bool] = OP_VARPCK_LG2(0), + [kRepeatedBase + kUpb_FieldType_String] = kUpb_DecodeOp_String, + [kRepeatedBase + kUpb_FieldType_Group] = kUpb_DecodeOp_SubMessage, + [kRepeatedBase + kUpb_FieldType_Message] = kUpb_DecodeOp_SubMessage, + [kRepeatedBase + kUpb_FieldType_Bytes] = kUpb_DecodeOp_Bytes, + [kRepeatedBase + kUpb_FieldType_UInt32] = OP_VARPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_Enum] = kUpb_DecodeOp_PackedEnum, + [kRepeatedBase + kUpb_FieldType_SFixed32] = OP_FIXPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_SFixed64] = OP_FIXPCK_LG2(3), + [kRepeatedBase + kUpb_FieldType_SInt32] = OP_VARPCK_LG2(2), + [kRepeatedBase + kUpb_FieldType_SInt64] = OP_VARPCK_LG2(3), + // Omitting kUpb_FakeFieldType_MessageSetItem, because we never emit a + // repeated msgset type + }; + + int ndx = field->UPB_PRIVATE(descriptortype); + if (upb_MiniTableField_IsArray(field)) ndx += kRepeatedBase; + int op = kDelimitedOps[ndx]; + + if (op == kUpb_DecodeOp_SubMessage) { + _upb_Decoder_CheckUnlinked(d, mt, field, &op); + } else if (op == kUpb_DecodeOp_Bytes) { + _upb_Decoder_MaybeVerifyUtf8(d, field, &op); + } + + return op; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr, + const upb_MiniTable* mt, + const upb_MiniTableField* field, + uint32_t wire_type, wireval* val, + int* op) { + static const unsigned kFixed32OkMask = (1 << kUpb_FieldType_Float) | + (1 << kUpb_FieldType_Fixed32) | + (1 << kUpb_FieldType_SFixed32); + + static const unsigned kFixed64OkMask = (1 << kUpb_FieldType_Double) | + (1 << kUpb_FieldType_Fixed64) | + (1 << kUpb_FieldType_SFixed64); + + switch (wire_type) { + case kUpb_WireType_Varint: + ptr = upb_WireReader_ReadVarint(ptr, &val->uint64_val, EPS(d)); + if (upb_MiniTableField_IsClosedEnum(field)) { + const upb_MiniTableEnum* e = upb_MiniTable_GetSubEnumTable(field); + if (!upb_MiniTableEnum_CheckValue(e, val->uint64_val)) { + *op = kUpb_DecodeOp_UnknownField; + return ptr; + } + _upb_Decoder_MungeInt32(val); + } else { + _upb_Decoder_Munge(field, val); + } + *op = _upb_Decoder_GetVarintOp(field); + return ptr; + case kUpb_WireType_32Bit: + *op = kUpb_DecodeOp_Scalar4Byte; + if (((1 << field->UPB_PRIVATE(descriptortype)) & kFixed32OkMask) == 0) { + *op = kUpb_DecodeOp_UnknownField; + } + return upb_WireReader_ReadFixed32(ptr, &val->uint32_val, &d->input); + case kUpb_WireType_64Bit: + *op = kUpb_DecodeOp_Scalar8Byte; + if (((1 << field->UPB_PRIVATE(descriptortype)) & kFixed64OkMask) == 0) { + *op = kUpb_DecodeOp_UnknownField; + } + return upb_WireReader_ReadFixed64(ptr, &val->uint64_val, &d->input); + case kUpb_WireType_Delimited: + ptr = upb_Decoder_DecodeSize(d, ptr, &val->size); + *op = _upb_Decoder_GetDelimitedOp(d, mt, field); + return ptr; + case kUpb_WireType_StartGroup: + val->uint32_val = field->UPB_PRIVATE(number); + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { + *op = kUpb_DecodeOp_SubMessage; + _upb_Decoder_CheckUnlinked(d, mt, field, op); + } else if (field->UPB_PRIVATE(descriptortype) == + kUpb_FakeFieldType_MessageSetItem) { + *op = kUpb_DecodeOp_MessageSetItem; + } else { + *op = kUpb_DecodeOp_UnknownField; + } + return ptr; + default: + break; + } + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTableField* field, + int op, wireval* val) { + uint8_t mode = field->UPB_PRIVATE(mode); + + if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) { + const upb_MiniTableExtension* ext_layout = + (const upb_MiniTableExtension*)field; + upb_Extension* ext = UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + msg, ext_layout, &d->arena); + if (UPB_UNLIKELY(!ext)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + d->original_msg = msg; + msg = &ext->data.UPB_PRIVATE(ext_msg_val); + } + + switch (mode & kUpb_FieldMode_Mask) { + case kUpb_FieldMode_Array: + return _upb_Decoder_DecodeToArray(d, ptr, msg, field, val, op); + case kUpb_FieldMode_Map: + return _upb_Decoder_DecodeToMap(d, ptr, msg, field, val); + case kUpb_FieldMode_Scalar: + return _upb_Decoder_DecodeToSubMessage(d, ptr, msg, field, val, op); + default: + UPB_UNREACHABLE(); + } +} + +static const char* _upb_Decoder_DecodeUnknownField( + upb_Decoder* d, const char* ptr, upb_Message* msg, uint32_t field_number, + uint32_t wire_type, wireval val, const char* start) { + if (field_number == 0) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } + + upb_EpsCopyInputStream_StartCapture(&d->input, start); + + if (wire_type == kUpb_WireType_Delimited) { + upb_StringView sv; + ptr = upb_EpsCopyInputStream_ReadStringEphemeral(&d->input, ptr, val.size, + &sv); + if (!ptr) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed); + } else if (wire_type == kUpb_WireType_StartGroup) { + ptr = UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, field_number << 3, + d->depth, &d->input); + } + + upb_StringView sv; + upb_EpsCopyInputStream_EndCapture(&d->input, ptr, &sv); + + upb_AddUnknownMode mode = kUpb_AddUnknown_Copy; + if (d->options & kUpb_DecodeOption_AliasString) { + if (sv.data != d->input.buffer_start) { + // If the data is not from the beginning of the input buffer, then we can + // safely attempt to coalesce this region with the previous one. + mode = kUpb_AddUnknown_AliasAllowMerge; + } else { + mode = kUpb_AddUnknown_Alias; + } + } + + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, sv.data, sv.size, &d->arena, + mode)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory); + } + + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr, + uint32_t* field_number, + uint32_t* wire_type) { + uint32_t tag; + UPB_ASSERT(ptr < d->input.limit_ptr); + ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d)); + *field_number = tag >> 3; + *wire_type = tag & 7; + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFieldData( + upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* mt, + uint32_t field_number, uint32_t wire_type, const char* start) { + int op; + wireval val; + + const upb_MiniTableField* field = + _upb_Decoder_FindField(d, mt, field_number, wire_type); + ptr = _upb_Decoder_DecodeWireValue(d, ptr, mt, field, wire_type, &val, &op); + + if (op >= 0) { + return _upb_Decoder_DecodeKnownField(d, ptr, msg, field, op, &val); + } else { + switch (op) { + case kUpb_DecodeOp_UnknownField: + return _upb_Decoder_DecodeUnknownField(d, ptr, msg, field_number, + wire_type, val, start); + case kUpb_DecodeOp_MessageSetItem: + return upb_Decoder_DecodeMessageSetItem(d, ptr, msg, mt); + default: + UPB_UNREACHABLE(); + } + } +} + +static const char* _upb_Decoder_EndMessage(upb_Decoder* d, const char* ptr) { + d->message_is_done = true; + return ptr; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeFieldNoFast(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* mt) { + uint32_t field_number; + uint32_t wire_type; + + const char* start = ptr; + ptr = _upb_Decoder_DecodeFieldTag(d, ptr, &field_number, &wire_type); + + if (wire_type == kUpb_WireType_EndGroup) { + d->end_group = field_number; + return _upb_Decoder_EndMessage(d, ptr); + } + + ptr = _upb_Decoder_DecodeFieldData(d, ptr, msg, mt, field_number, wire_type, + start); + _upb_Decoder_Trace(d, 'M'); + return ptr; +} + +UPB_FORCEINLINE +bool _upb_Decoder_TryDecodeMessageFast(upb_Decoder* d, const char** ptr, + upb_Message* msg, + const upb_MiniTable* mt, + uint64_t last_field_index, + uint64_t data) { +#ifdef UPB_ENABLE_FASTTABLE + if (mt->UPB_PRIVATE(table_mask) == (unsigned char)-1 || + (d->options & kUpb_DecodeOption_DisableFastTable)) { + // Fast table is unavailable or disabled. + return false; + } + + intptr_t table = decode_totable(mt); + const char* start = *ptr; + char* trace_next = _upb_Decoder_TraceNext(d); + + *ptr = upb_DecodeFast_Dispatch(d, *ptr, msg, table, 0, 0); + + if (d->message_is_done) { + // The entire message was successfully parsed fast. + return true; + } + + // *ptr now points to the beginning of a field that could not be parsed fast. + // It's possible that some fields were parsed fast, in which case *ptr will + // have been updated. However, it's also possible that the very first field + // encountered could not be parsed fast, in which case *ptr will be unchanged. + // + // If the fast decoder consumed any data, it must have emitted at least + // one 'F' event into the trace buffer (in addition to the 'D' event + // that is always emitted). + UPB_ASSERT(_upb_Decoder_TracePtr(d) != trace_next || *ptr == start); + _upb_Decoder_Trace(d, '<'); +#endif + return false; +} + +UPB_FORCEINLINE +const char* _upb_Decoder_DecodeField(upb_Decoder* d, const char* ptr, + upb_Message* msg, const upb_MiniTable* mt, + uint64_t last_field_index, uint64_t data) { + if (_upb_Decoder_TryDecodeMessageFast(d, &ptr, msg, mt, last_field_index, + data)) { + return ptr; + } else if (upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) { + return _upb_Decoder_EndMessage(d, ptr); + } + + return _upb_Decoder_DecodeFieldNoFast(d, ptr, msg, mt); +} + +UPB_NOINLINE +const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* mt) { + UPB_ASSERT(mt); + UPB_ASSERT(d->message_is_done == false); + + do { + ptr = _upb_Decoder_DecodeField(d, ptr, msg, mt, 0, 0); + } while (!d->message_is_done); + d->message_is_done = false; + + return UPB_UNLIKELY(mt && mt->UPB_PRIVATE(required_count)) + ? _upb_Decoder_CheckRequired(d, ptr, msg, mt) + : ptr; +} + +static upb_DecodeStatus _upb_Decoder_DecodeTop(struct upb_Decoder* d, + const char* buf, + upb_Message* msg, + const upb_MiniTable* m) { + _upb_Decoder_DecodeMessage(d, buf, msg, m); + if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed; + if (d->missing_required) return kUpb_DecodeStatus_MissingRequired; + return kUpb_DecodeStatus_Ok; +} + +static upb_DecodeStatus upb_Decoder_Decode(upb_Decoder* const decoder, + const char* const buf, + upb_Message* const msg, + const upb_MiniTable* const m, + upb_Arena* const arena) { + if (UPB_SETJMP(decoder->err.buf) == 0) { + decoder->err.code = _upb_Decoder_DecodeTop(decoder, buf, msg, m); + } else { + UPB_ASSERT(decoder->err.code != kUpb_DecodeStatus_Ok); + } + + return upb_Decoder_Destroy(decoder, arena); +} + +static uint16_t upb_DecodeOptions_GetMaxDepth(uint32_t options) { + return options >> 16; +} + +uint16_t upb_DecodeOptions_GetEffectiveMaxDepth(uint32_t options) { + uint16_t max_depth = upb_DecodeOptions_GetMaxDepth(options); + return max_depth ? max_depth : kUpb_WireFormat_DefaultDepthLimit; +} + +upb_DecodeStatus upb_Decode(const char* buf, size_t size, upb_Message* msg, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Decoder decoder; + buf = upb_Decoder_Init(&decoder, buf, size, extreg, options, arena, NULL, 0); + + return upb_Decoder_Decode(&decoder, buf, msg, mt, arena); +} + +upb_DecodeStatus upb_DecodeWithTrace(const char* buf, size_t size, + upb_Message* msg, const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena, + char* trace_buf, size_t trace_size) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Decoder decoder; + buf = upb_Decoder_Init(&decoder, buf, size, extreg, options, arena, trace_buf, + trace_size); + + return upb_Decoder_Decode(&decoder, buf, msg, mt, arena); +} + +upb_DecodeStatus upb_DecodeLengthPrefixed(const char* buf, size_t size, + upb_Message* msg, + size_t* num_bytes_read, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + // To avoid needing to make a Decoder just to decode the initial length, + // hand-decode the leading varint for the message length here. + uint64_t msg_len = 0; + for (size_t i = 0;; ++i) { + if (i >= size || i > 9) { + return kUpb_DecodeStatus_Malformed; + } + uint64_t b = *buf; + buf++; + msg_len += (b & 0x7f) << (i * 7); + if ((b & 0x80) == 0) { + *num_bytes_read = i + 1 + msg_len; + break; + } + } + + // If the total number of bytes we would read (= the bytes from the varint + // plus however many bytes that varint says we should read) is larger then the + // input buffer then error as malformed. + if (*num_bytes_read > size) { + return kUpb_DecodeStatus_Malformed; + } + if (msg_len > INT32_MAX) { + return kUpb_DecodeStatus_Malformed; + } + + return upb_Decode(buf, msg_len, msg, mt, extreg, options, arena); +} + +const char* upb_DecodeStatus_String(upb_DecodeStatus status) { + switch (status) { + case kUpb_DecodeStatus_Ok: + return "Ok"; + case kUpb_DecodeStatus_Malformed: + return "Wire format was corrupt"; + case kUpb_DecodeStatus_OutOfMemory: + return "Arena alloc failed"; + case kUpb_DecodeStatus_BadUtf8: + return "String field had bad UTF-8"; + case kUpb_DecodeStatus_MaxDepthExceeded: + return "Exceeded upb_DecodeOptions_MaxDepth"; + case kUpb_DecodeStatus_MissingRequired: + return "Missing required field"; + default: + return "Unknown decode status"; + } +} + +#undef OP_FIXPCK_LG2 +#undef OP_VARPCK_LG2 + +// We encode backwards, to avoid pre-computing lengths (one-pass encode). + + +#include <setjmp.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Must be last. + +static uint32_t encode_zz32(int32_t n) { + return ((uint32_t)n << 1) ^ (n >> 31); +} +static uint64_t encode_zz64(int64_t n) { + return ((uint64_t)n << 1) ^ (n >> 63); +} + +typedef struct { + upb_EncodeStatus status; + jmp_buf err; + upb_Arena* arena; + // These should only be used for arithmetic and reallocation to allow full + // aliasing analysis on the ptr argument. + const char UPB_NODEREF *buf, *limit; + int options; + int depth; + _upb_mapsorter sorter; +} upb_encstate; + +UPB_NORETURN static void encode_err(upb_encstate* e, upb_EncodeStatus s) { + UPB_ASSERT(s != kUpb_EncodeStatus_Ok); + e->status = s; + UPB_LONGJMP(e->err, 1); +} + +// Subtraction is used for bounds checks, and the C standard says that pointer +// subtraction is UB if the pointers aren't part of the same array or one past +// the end, so we must avoid NULL - NULL. C++ defines it though. +static char initial_buf_sentinel; + +UPB_NOINLINE static char* encode_growbuffer(char* ptr, upb_encstate* e, + size_t bytes) { + size_t old_size = e->limit - e->buf; + size_t needed_size = bytes + (e->limit - ptr); + if (needed_size < bytes) encode_err(e, kUpb_EncodeStatus_OutOfMemory); + size_t new_size = upb_RoundUpToPowerOfTwo(UPB_MAX(128, needed_size)); + if (new_size == old_size) encode_err(e, kUpb_EncodeStatus_OutOfMemory); + void* old_buf = e->buf == &initial_buf_sentinel ? NULL : (void*)e->buf; + char* new_buf = upb_Arena_Realloc(e->arena, old_buf, old_size, new_size); + + if (!new_buf) encode_err(e, kUpb_EncodeStatus_OutOfMemory); + + // We want previous data at the end, realloc() put it at the beginning. + // TODO: This is somewhat inefficient since we are copying twice. + // Maybe create a realloc() that copies to the end of the new buffer? + if (old_size > 0) { + memmove(new_buf + new_size - old_size, new_buf, old_size); + } + + e->buf = new_buf; + e->limit = new_buf + new_size; + return new_buf + new_size - needed_size; +} + +/* Call to ensure that at least `bytes` bytes are available for writing at + * ptr. */ +UPB_FORCEINLINE +char* encode_reserve(char* ptr, upb_encstate* e, size_t bytes) { + if ((size_t)(ptr - e->buf) < bytes) { + return encode_growbuffer(ptr, e, bytes); + } + + return ptr - bytes; +} + +static char* encode_bytes_unchecked(char* ptr, upb_encstate* e, + const void* data, size_t len) { + if (len == 0) return ptr; /* memcpy() with zero size is UB */ + ptr -= len; + memcpy(ptr, data, len); + return ptr; +} + +/* Writes the given bytes to the buffer, handling reserve/advance. */ +static char* encode_bytes(char* ptr, upb_encstate* e, const void* data, + size_t len) { + if (len == 0) return ptr; /* memcpy() with zero size is UB */ + ptr = encode_reserve(ptr, e, len); + memcpy(ptr, data, len); + return ptr; +} + +static char* encode_fixed64_unchecked(char* ptr, upb_encstate* e, + uint64_t val) { + val = upb_BigEndian64(val); + return encode_bytes_unchecked(ptr, e, &val, sizeof(uint64_t)); +} + +static char* encode_fixed32_unchecked(char* ptr, upb_encstate* e, + uint32_t val) { + val = upb_BigEndian32(val); + return encode_bytes_unchecked(ptr, e, &val, sizeof(uint32_t)); +} + +#define UPB_PB_VARINT_MAX_LEN 10 +#define UPB_PB_VARINT32_MAX_LEN 5 + +#if UPB_ARM64_ASM +// Each arm64 instruction encodes to 4 bytes, and it takes two intructions +// to process each byte of output, so we branch ahead by (4 + 4) * skip to +// avoid the remaining bytes. When BTI is on, we need to use specific +// "landing pad" instructions, so we pad those with nop to make it a power +// of 2, skipping 16 bytes at each stage instead of 8. This carries some +// overhead especially on in-order cores so they're not included unless +// building with branch protection. +#if UPB_ARM64_BTI_DEFAULT +// BTI is used with jc targets here because we don't control which register will +// be used for addr; if it's x16 or x17 a `br` is treated like a call. +#define UPB_BTI_JC "bti jc\n" +#define UPB_BTI_NOP "nop\n" +#define UPB_BTI_SHIFT_IMM "4\n" +#else +#define UPB_BTI_JC +#define UPB_BTI_NOP +#define UPB_BTI_SHIFT_IMM "3\n" +#endif +UPB_NOINLINE static char* encode_longvarint(char* ptr, upb_encstate* e, + uint64_t val) { + ptr = encode_reserve(ptr, e, UPB_PB_VARINT_MAX_LEN); + uint64_t clz; + __asm__("clz %[cnt], %[val]\n" : [cnt] "=r"(clz) : [val] "r"(val)); + + uint32_t skip = + UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(clz); + + ptr += skip; + uint64_t addr, mask; + __asm__ volatile( + // Formatter keeps merging short lines + // clang-format off + "adr %[addr], 0f\n" + "add %[addr], %[addr], %[cnt], lsl #" UPB_BTI_SHIFT_IMM + "mov %w[mask], #0x80\n" + "br %[addr]\n" + // Work around llvm/llvm-project#47432, where alignment directives inside + // functions crash the compiler when generating SEH info on windows. + #ifndef __SEH__ + ".p2align " UPB_BTI_SHIFT_IMM + #endif + "0:\n" + // We don't need addr any more, but we've got the register for our whole + // assembly block so we'll use it as scratch to store the shift+masked + // values before storing them. + // The following stores are unsigned offset stores: + // strb Wt, [Xn, #imm] + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #56\n" + "strb %w[addr], [%[ptr], #8]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #49\n" + "strb %w[addr], [%[ptr], #7]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #42\n" + "strb %w[addr], [%[ptr], #6]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #35\n" + "strb %w[addr], [%[ptr], #5]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %[addr], %[mask], %[val], lsr #28\n" + "strb %w[addr], [%[ptr], #4]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[mask], %w[val], lsr #21\n" + "strb %w[addr], [%[ptr], #3]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[mask], %w[val], lsr #14\n" + "strb %w[addr], [%[ptr], #2]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[mask], %w[val], lsr #7\n" + "strb %w[addr], [%[ptr], #1]\n" + UPB_BTI_NOP + + UPB_BTI_JC + "orr %w[addr], %w[val], #0x80\n" + "strb %w[addr], [%[ptr]]\n" + UPB_BTI_NOP + + UPB_BTI_JC + // clang-format on + : [addr] "=&r"(addr), [mask] "=&r"(mask) + : [val] "r"(val), [ptr] "r"(ptr), [cnt] "r"((uint64_t)skip) + : "memory"); + uint32_t continuations = UPB_PB_VARINT_MAX_LEN - 1 - skip; + // msan can't instrument stores in inline assembly + UPB_PRIVATE(upb_Xsan_MarkInitialized)(ptr, continuations); + // Encode the final byte after the continuation bytes. + ptr[continuations] = val >> (7 * continuations); + return ptr; +} +#undef UPB_BTI_JC +#undef UPB_BTI_NOP +#undef UPB_BTI_SHIFT_IMM +#else +UPB_NOINLINE +static char* encode_longvarint(char* ptr, upb_encstate* e, uint64_t val) { + ptr = encode_reserve(ptr, e, UPB_PB_VARINT_MAX_LEN); + size_t len = 0; + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + ptr[len++] = byte; + } while (val); + char* start = ptr + UPB_PB_VARINT_MAX_LEN - len; + memmove(start, ptr, len); + return start; +} +#endif + +UPB_FORCEINLINE +char* encode_varint_unchecked(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longvarint(ptr, e, val); + } +} +UPB_FORCEINLINE +char* encode_varint(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128 && ptr != e->buf) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longvarint(ptr, e, val); + } +} + +UPB_NOINLINE +char* encode_longlength(char* ptr, upb_encstate* e, uint64_t val) { + if (val > INT32_MAX) { + encode_err(e, kUpb_EncodeStatus_MaxSizeExceeded); + } + return encode_longvarint(ptr, e, val); +} + +UPB_FORCEINLINE +char* encode_length(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128 && ptr != e->buf) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longlength(ptr, e, val); + } +} + +UPB_FORCEINLINE +char* encode_length_unchecked(char* ptr, upb_encstate* e, uint64_t val) { + if (val < 128) { + --ptr; + *ptr = val; + return ptr; + } else { + return encode_longlength(ptr, e, val); + } +} + +static char* encode_double_unchecked(char* ptr, upb_encstate* e, double d) { + uint64_t u64; + UPB_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "bad double size"); + memcpy(&u64, &d, sizeof(uint64_t)); + return encode_fixed64_unchecked(ptr, e, u64); +} + +static char* encode_float_unchecked(char* ptr, upb_encstate* e, float d) { + uint32_t u32; + UPB_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "bad float size"); + memcpy(&u32, &d, sizeof(uint32_t)); + return encode_fixed32_unchecked(ptr, e, u32); +} + +static char* encode_tag_unchecked(char* ptr, upb_encstate* e, + uint32_t field_number, uint8_t wire_type) { + return encode_varint_unchecked(ptr, e, (field_number << 3) | wire_type); +} + +static char* encode_tag(char* ptr, upb_encstate* e, uint32_t field_number, + uint8_t wire_type) { + return encode_varint(ptr, e, (field_number << 3) | wire_type); +} + +static char* encode_fixedarray(char* ptr, upb_encstate* e, const upb_Array* arr, + size_t elem_size, uint32_t tag) { + size_t bytes = upb_Array_Size(arr) * elem_size; + const char* data = upb_Array_DataPtr(arr); + const char* arr_ptr = data + bytes - elem_size; + + if (tag || !upb_IsLittleEndian()) { + while (true) { + if (elem_size == 4) { + uint32_t val; + memcpy(&val, arr_ptr, sizeof(val)); + val = upb_BigEndian32(val); + ptr = encode_bytes(ptr, e, &val, elem_size); + } else { + UPB_ASSERT(elem_size == 8); + uint64_t val; + memcpy(&val, arr_ptr, sizeof(val)); + val = upb_BigEndian64(val); + ptr = encode_bytes(ptr, e, &val, elem_size); + } + + if (tag) { + ptr = encode_varint(ptr, e, tag); + } + if (arr_ptr == data) break; + arr_ptr -= elem_size; + } + return ptr; + } else { + return encode_bytes(ptr, e, data, bytes); + } +} + +static char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size); + +static char* encode_scalar(char* ptr, upb_encstate* e, const void* field_mem, + const upb_MiniTableField* f) { + // Max size is tag + 10 bytes for max varint or 8 for largest fixed size +#define CASE(ctype, type, wtype, encodeval) \ + { \ + const size_t bytes = UPB_PB_VARINT32_MAX_LEN + UPB_PB_VARINT_MAX_LEN; \ + ptr = encode_reserve(ptr, e, bytes); \ + ptr += bytes; \ + const ctype val = *(const ctype*)field_mem; \ + ptr = encode_##type##_unchecked(ptr, e, encodeval); \ + return encode_tag_unchecked(ptr, e, upb_MiniTableField_Number(f), wtype); \ + } + + switch (f->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Double: + CASE(double, double, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Float: + CASE(float, float, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: + CASE(uint64_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_UInt32: + CASE(uint32_t, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: + CASE(int32_t, varint, kUpb_WireType_Varint, (int64_t)val); + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + CASE(uint64_t, fixed64, kUpb_WireType_64Bit, val); + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + CASE(uint32_t, fixed32, kUpb_WireType_32Bit, val); + case kUpb_FieldType_Bool: + CASE(bool, varint, kUpb_WireType_Varint, val); + case kUpb_FieldType_SInt32: + CASE(int32_t, varint, kUpb_WireType_Varint, encode_zz32(val)); + case kUpb_FieldType_SInt64: + CASE(int64_t, varint, kUpb_WireType_Varint, encode_zz64(val)); + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + upb_StringView view = *(upb_StringView*)field_mem; + const size_t max_size = + UPB_PB_VARINT32_MAX_LEN + UPB_PB_VARINT32_MAX_LEN + view.size; + ptr = encode_reserve(ptr, e, max_size); + ptr += max_size; + ptr = encode_bytes_unchecked(ptr, e, view.data, view.size); + ptr = encode_length_unchecked(ptr, e, view.size); + return encode_tag_unchecked(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } + case kUpb_FieldType_Group: { + size_t size; + upb_Message* submsg = *(upb_Message**)field_mem; + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (submsg == 0) { + return ptr; + } + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_EndGroup); + ptr = encode_message(ptr, e, submsg, subm, &size); + e->depth++; + return encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_StartGroup); + } + case kUpb_FieldType_Message: { + size_t size; + upb_Message* submsg = *(upb_Message**)field_mem; + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (submsg == 0) { + return ptr; + } + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + ptr = encode_message(ptr, e, submsg, subm, &size); + e->depth++; + size_t max_size = UPB_PB_VARINT32_MAX_LEN + UPB_PB_VARINT32_MAX_LEN; + ptr = encode_reserve(ptr, e, max_size); + ptr += max_size; + ptr = encode_length_unchecked(ptr, e, size); + return encode_tag_unchecked(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } + default: + UPB_UNREACHABLE(); + } +#undef CASE +} + +static char* encode_array(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTableField* f) { + const upb_Array* arr = *UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), upb_Array*); + bool packed = upb_MiniTableField_IsPacked(f); + size_t pre_len = e->limit - ptr; + + if (arr == NULL || upb_Array_Size(arr) == 0) { + return ptr; + } + +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype* start = upb_Array_DataPtr(arr); \ + const ctype* arr_ptr = start + upb_Array_Size(arr); \ + uint32_t tag = \ + packed ? 0 : (f->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; \ + do { \ + arr_ptr--; \ + ptr = encode_varint(ptr, e, encode); \ + if (tag) { \ + ptr = encode_varint(ptr, e, tag); \ + } \ + } while (arr_ptr != start); \ + } \ + break; + +#define TAG(wire_type) (packed ? 0 : (f->UPB_PRIVATE(number) << 3 | wire_type)) + + switch (f->UPB_PRIVATE(descriptortype)) { + case kUpb_FieldType_Double: + ptr = encode_fixedarray(ptr, e, arr, sizeof(double), + TAG(kUpb_WireType_64Bit)); + break; + case kUpb_FieldType_Float: + ptr = encode_fixedarray(ptr, e, arr, sizeof(float), + TAG(kUpb_WireType_32Bit)); + break; + case kUpb_FieldType_SFixed64: + case kUpb_FieldType_Fixed64: + ptr = encode_fixedarray(ptr, e, arr, sizeof(uint64_t), + TAG(kUpb_WireType_64Bit)); + break; + case kUpb_FieldType_Fixed32: + case kUpb_FieldType_SFixed32: + ptr = encode_fixedarray(ptr, e, arr, sizeof(uint32_t), + TAG(kUpb_WireType_32Bit)); + break; + case kUpb_FieldType_Int64: + case kUpb_FieldType_UInt64: + VARINT_CASE(uint64_t, *arr_ptr); + case kUpb_FieldType_UInt32: + VARINT_CASE(uint32_t, *arr_ptr); + case kUpb_FieldType_Int32: + case kUpb_FieldType_Enum: + VARINT_CASE(int32_t, (int64_t)*arr_ptr); + case kUpb_FieldType_Bool: + VARINT_CASE(bool, *arr_ptr); + case kUpb_FieldType_SInt32: + VARINT_CASE(int32_t, encode_zz32(*arr_ptr)); + case kUpb_FieldType_SInt64: + VARINT_CASE(int64_t, encode_zz64(*arr_ptr)); + case kUpb_FieldType_String: + case kUpb_FieldType_Bytes: { + const upb_StringView* start = upb_Array_DataPtr(arr); + const upb_StringView* str_ptr = start + upb_Array_Size(arr); + do { + str_ptr--; + ptr = encode_bytes(ptr, e, str_ptr->data, str_ptr->size); + ptr = encode_length(ptr, e, str_ptr->size); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } while (str_ptr != start); + return ptr; + } + case kUpb_FieldType_Group: { + const upb_Message* const* start = upb_Array_DataPtr(arr); + const upb_Message* const* arr_ptr = start + upb_Array_Size(arr); + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + do { + size_t size; + arr_ptr--; + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_EndGroup); + ptr = encode_message(ptr, e, *arr_ptr, subm, &size); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_StartGroup); + } while (arr_ptr != start); + e->depth++; + return ptr; + } + case kUpb_FieldType_Message: { + const upb_Message* const* start = upb_Array_DataPtr(arr); + const upb_Message* const* arr_ptr = start + upb_Array_Size(arr); + const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f); + if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); + do { + size_t size; + arr_ptr--; + ptr = encode_message(ptr, e, *arr_ptr, subm, &size); + ptr = encode_length(ptr, e, size); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } while (arr_ptr != start); + e->depth++; + return ptr; + } + } +#undef VARINT_CASE + + if (packed) { + ptr = encode_length(ptr, e, e->limit - ptr - pre_len); + ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f), + kUpb_WireType_Delimited); + } + return ptr; +} + +static char* encode_mapentry(char* ptr, upb_encstate* e, uint32_t number, + const upb_MiniTable* layout, + const upb_MapEntry* ent) { + const upb_MiniTableField* key_field = upb_MiniTable_MapKey(layout); + const upb_MiniTableField* val_field = upb_MiniTable_MapValue(layout); + size_t pre_len = e->limit - ptr; + size_t size; + ptr = encode_scalar(ptr, e, &ent->v, val_field); + ptr = encode_scalar(ptr, e, &ent->k, key_field); + size = (e->limit - ptr) - pre_len; + ptr = encode_length(ptr, e, size); + ptr = encode_tag(ptr, e, number, kUpb_WireType_Delimited); + return ptr; +} + +static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTableField* f) { + const upb_Map* map = *UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), const upb_Map*); + const upb_MiniTable* layout = upb_MiniTable_MapEntrySubMessage(f); + UPB_ASSERT(upb_MiniTable_FieldCount(layout) == 2); + + if (!map || !upb_Map_Size(map)) return ptr; + + if (e->options & kUpb_EncodeOption_Deterministic) { + if (!map->UPB_PRIVATE(is_strtable)) { + // For inttable, first encode the array part, then sort the table entries. + intptr_t iter = UPB_INTTABLE_BEGIN; + while ((size_t)++iter < map->t.inttable.array_size) { + upb_value value = map->t.inttable.array[iter]; + if (upb_inttable_arrhas(&map->t.inttable, iter)) { + upb_MapEntry ent; + memcpy(&ent.k, &iter, sizeof(iter)); + _upb_map_fromvalue(value, &ent.v, map->val_size); + ptr = encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, + &ent); + } + } + } + _upb_sortedmap sorted; + _upb_mapsorter_pushmap( + &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), + map, &sorted); + upb_MapEntry ent; + while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { + ptr = encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); + } + _upb_mapsorter_popmap(&e->sorter, &sorted); + } else { + upb_value val; + if (map->UPB_PRIVATE(is_strtable)) { + intptr_t iter = UPB_STRTABLE_BEGIN; + upb_StringView strkey; + while (upb_strtable_next2(&map->t.strtable, &strkey, &val, &iter)) { + upb_MapEntry ent; + _upb_map_fromkey(strkey, &ent.k, map->key_size); + _upb_map_fromvalue(val, &ent.v, map->val_size); + ptr = + encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); + } + } else { + intptr_t iter = UPB_INTTABLE_BEGIN; + uintptr_t intkey = 0; + while (upb_inttable_next(&map->t.inttable, &intkey, &val, &iter)) { + upb_MapEntry ent; + memcpy(&ent.k, &intkey, map->key_size); + _upb_map_fromvalue(val, &ent.v, map->val_size); + ptr = + encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); + } + } + } + return ptr; +} + +static bool encode_shouldencode(const upb_Message* msg, + const upb_MiniTableField* f) { + if (f->presence == 0) { + // Proto3 presence or map/array. + const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void); + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: { + char ch; + memcpy(&ch, mem, 1); + return ch != 0; + } + case kUpb_FieldRep_4Byte: { + uint32_t u32; + memcpy(&u32, mem, 4); + return u32 != 0; + } + case kUpb_FieldRep_8Byte: { + uint64_t u64; + memcpy(&u64, mem, 8); + return u64 != 0; + } + case kUpb_FieldRep_StringView: { + const upb_StringView* str = (const upb_StringView*)mem; + return str->size != 0; + } + default: + UPB_UNREACHABLE(); + } + } else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + // Proto2 presence: hasbit. + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); + } else { + // Field is in a oneof. + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == + upb_MiniTableField_Number(f); + } +} + +static char* encode_field(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTableField* field) { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { + case kUpb_FieldMode_Array: + return encode_array(ptr, e, msg, field); + case kUpb_FieldMode_Map: + return encode_map(ptr, e, msg, field); + case kUpb_FieldMode_Scalar: + return encode_scalar( + ptr, e, UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void), field); + default: + UPB_UNREACHABLE(); + } +} + +static char* encode_msgset_item(char* ptr, upb_encstate* e, + const upb_MiniTableExtension* ext, + const upb_MessageValue ext_val) { + size_t size; + ptr = encode_tag(ptr, e, kUpb_MsgSet_Item, kUpb_WireType_EndGroup); + ptr = encode_message(ptr, e, ext_val.msg_val, + upb_MiniTableExtension_GetSubMessage(ext), &size); + ptr = encode_varint(ptr, e, size); + ptr = encode_tag(ptr, e, kUpb_MsgSet_Message, kUpb_WireType_Delimited); + ptr = encode_varint(ptr, e, upb_MiniTableExtension_Number(ext)); + ptr = encode_tag(ptr, e, kUpb_MsgSet_TypeId, kUpb_WireType_Varint); + ptr = encode_tag(ptr, e, kUpb_MsgSet_Item, kUpb_WireType_StartGroup); + return ptr; +} + +static char* encode_ext(char* ptr, upb_encstate* e, + const upb_MiniTableExtension* ext, + upb_MessageValue ext_val, bool is_message_set) { + if (UPB_UNLIKELY(is_message_set)) { + ptr = encode_msgset_item(ptr, e, ext, ext_val); + } else { + ptr = encode_field(ptr, e, &ext_val.UPB_PRIVATE(ext_msg_val), + &ext->UPB_PRIVATE(field)); + } + return ptr; +} + +static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m, + const upb_Message* msg) { + if (m->UPB_PRIVATE(ext) == kUpb_ExtMode_NonExtendable) return ptr; + + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return ptr; + + /* Encode all extensions together. Unlike C++, we do not attempt to keep + * these in field number order relative to normal fields or even to each + * other. */ + uintptr_t iter = kUpb_Message_ExtensionBegin; + const upb_MiniTableExtension* ext; + upb_MessageValue ext_val; + if (!UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, &ext, &ext_val, + &iter)) { + // Message has no extensions. + return ptr; + } + + if (e->options & kUpb_EncodeOption_Deterministic) { + _upb_sortedmap sorted; + if (!_upb_mapsorter_pushexts(&e->sorter, in, &sorted)) { + // TODO: b/378744096 - handle alloc failure + } + const upb_Extension* ext; + while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { + ptr = encode_ext(ptr, e, ext->ext, ext->data, + m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); + } + _upb_mapsorter_popmap(&e->sorter, &sorted); + } else { + do { + ptr = encode_ext(ptr, e, ext, ext_val, + m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); + } while (UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, &ext, &ext_val, + &iter)); + } + return ptr; +} + +static char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size) { + size_t pre_len = e->limit - ptr; + + if (e->options & kUpb_EncodeOption_CheckRequired) { + if (m->UPB_PRIVATE(required_count)) { + if (!UPB_PRIVATE(_upb_Message_IsInitializedShallow)(msg, m)) { + encode_err(e, kUpb_EncodeStatus_MissingRequired); + } + } + } + + if ((e->options & kUpb_EncodeOption_SkipUnknown) == 0) { + size_t unknown_size = 0; + uintptr_t iter = kUpb_Message_UnknownBegin; + upb_StringView unknown; + // Need to write in reverse order, but iteration is in-order; scan to + // reserve capacity up front, then write in-order + while (upb_Message_NextUnknown(msg, &unknown, &iter)) { + unknown_size += unknown.size; + } + if (unknown_size != 0) { + ptr = encode_reserve(ptr, e, unknown_size); + char* tmp_ptr = ptr; + iter = kUpb_Message_UnknownBegin; + while (upb_Message_NextUnknown(msg, &unknown, &iter)) { + memcpy(tmp_ptr, unknown.data, unknown.size); + tmp_ptr += unknown.size; + } + } + } + + ptr = encode_exts(ptr, e, m, msg); + + if (upb_MiniTable_FieldCount(m)) { + const upb_MiniTableField* f = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0]; + while (f != first) { + f--; + if (encode_shouldencode(msg, f)) { + ptr = encode_field(ptr, e, msg, f); + } + } + } + + *size = (e->limit - ptr) - pre_len; + return ptr; +} + +static upb_EncodeStatus upb_Encoder_Encode(char* ptr, + upb_encstate* const encoder, + const upb_Message* const msg, + const upb_MiniTable* const l, + char** const buf, size_t* const size, + bool prepend_len) { + // Unfortunately we must continue to perform hackery here because there are + // code paths which blindly copy the returned pointer without bothering to + // check for errors until much later (b/235839510). So we still set *buf to + // NULL on error and we still set it to non-NULL on a successful empty result. + if (UPB_SETJMP(encoder->err) == 0) { + size_t encoded_msg_size; + ptr = encode_message(ptr, encoder, msg, l, &encoded_msg_size); + if (prepend_len) { + ptr = encode_length(ptr, encoder, encoded_msg_size); + } + *size = encoder->limit - ptr; + if (*size == 0) { + static char ch; + *buf = &ch; + } else { + UPB_ASSERT(ptr); + *buf = ptr; + } + } else { + UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok); + *buf = NULL; + *size = 0; + } + + _upb_mapsorter_destroy(&encoder->sorter); + return encoder->status; +} + +static uint16_t upb_EncodeOptions_GetMaxDepth(uint32_t options) { + return options >> 16; +} + +uint16_t upb_EncodeOptions_GetEffectiveMaxDepth(uint32_t options) { + uint16_t max_depth = upb_EncodeOptions_GetMaxDepth(options); + return max_depth ? max_depth : kUpb_WireFormat_DefaultDepthLimit; +} + +static upb_EncodeStatus _upb_Encode(const upb_Message* msg, + const upb_MiniTable* l, int options, + upb_Arena* arena, char** buf, size_t* size, + bool prepend_len) { + upb_encstate e; + + e.status = kUpb_EncodeStatus_Ok; + e.arena = arena; + e.buf = &initial_buf_sentinel; + e.limit = &initial_buf_sentinel; + e.depth = upb_EncodeOptions_GetEffectiveMaxDepth(options); + e.options = options; + _upb_mapsorter_init(&e.sorter); + + return upb_Encoder_Encode(&initial_buf_sentinel, &e, msg, l, buf, size, + prepend_len); +} + +upb_EncodeStatus upb_Encode(const upb_Message* msg, const upb_MiniTable* l, + int options, upb_Arena* arena, char** buf, + size_t* size) { + return _upb_Encode(msg, l, options, arena, buf, size, false); +} + +upb_EncodeStatus upb_EncodeLengthPrefixed(const upb_Message* msg, + const upb_MiniTable* l, int options, + upb_Arena* arena, char** buf, + size_t* size) { + return _upb_Encode(msg, l, options, arena, buf, size, true); +} + +const char* upb_EncodeStatus_String(upb_EncodeStatus status) { + switch (status) { + case kUpb_EncodeStatus_Ok: + return "Ok"; + case kUpb_EncodeStatus_MissingRequired: + return "Missing required field"; + case kUpb_EncodeStatus_MaxDepthExceeded: + return "Max depth exceeded"; + case kUpb_EncodeStatus_OutOfMemory: + return "Arena alloc failed"; + default: + return "Unknown encode status"; + } +} + + + +// Must be last. + +UPB_NOINLINE +const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* m) { + UPB_ASSERT(m->UPB_PRIVATE(required_count)); + if (UPB_UNLIKELY(d->options & kUpb_DecodeOption_CheckRequired)) { + d->missing_required = + d->missing_required || + !UPB_PRIVATE(_upb_Message_IsInitializedShallow)(msg, m); + } + return ptr; +} + + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +const char* UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)( + upb_EpsCopyInputStream* e) { + e->error = true; + if (e->err) upb_ErrorHandler_ThrowError(e->err, kUpb_ErrorCode_Malformed); + return NULL; +} + +const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)( + struct upb_EpsCopyInputStream* e, const char* ptr, int overrun) { + if (overrun < e->limit) { + // Need to copy remaining data into patch buffer. + UPB_ASSERT(overrun < kUpb_EpsCopyInputStream_SlopBytes); + const char* old_end = ptr; + const char* new_start = &e->patch[overrun]; + memset(&e->patch[kUpb_EpsCopyInputStream_SlopBytes], 0, + kUpb_EpsCopyInputStream_SlopBytes); + memcpy(e->patch, e->end, kUpb_EpsCopyInputStream_SlopBytes); + ptr = new_start; + e->end = &e->patch[kUpb_EpsCopyInputStream_SlopBytes]; + e->limit -= kUpb_EpsCopyInputStream_SlopBytes; + e->limit_ptr = e->end + e->limit; + UPB_ASSERT(ptr < e->limit_ptr); + e->input_delta = (uintptr_t)old_end - (uintptr_t)new_start; + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + return new_start; + } else { + UPB_ASSERT(overrun > e->limit); + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } +} + + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint) + UPB_PRIVATE(_upb_WireReader_ReadLongVarint)( + const char* ptr, uint64_t val, upb_EpsCopyInputStream* stream) { + for (int i = 1; i < 10; i++) { + uint64_t byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val}; + } + } + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0}; +} + +UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint) + UPB_PRIVATE(_upb_WireReader_ReadLongTag)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream) { + for (int i = 1; i < 5; i++) { + uint64_t byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + if (val > UINT32_MAX) break; + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val}; + } + } + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0}; +} + +UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint) + UPB_PRIVATE(_upb_WireReader_ReadLongSize)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream) { + for (int i = 1; i < 5; i++) { + uint64_t byte = (uint8_t)ptr[i]; + val += (byte - 1) << (i * 7); + if (!(byte & 0x80)) { + if (val > INT32_MAX) break; + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val}; + } + } + return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0}; +} + +const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + if (--depth_limit < 0) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } + uint32_t end_group_tag = (tag & ~7ULL) | kUpb_WireType_EndGroup; + while (!upb_EpsCopyInputStream_IsDone(stream, &ptr)) { + uint32_t tag; + ptr = upb_WireReader_ReadTag(ptr, &tag, stream); + if (!ptr) break; + if (tag == end_group_tag) return ptr; + ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, stream); + if (!ptr) break; + } + // Encountered limit end before end group tag. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); +} + +// This should #undef all macros #defined in def.inc + +#undef UPB_SIZE +#undef UPB_PTR_AT +#undef UPB_SIZEOF_FLEX +#undef UPB_SIZEOF_FLEX_WOULD_OVERFLOW +#undef UPB_MAPTYPE_STRING +#undef UPB_EXPORT +#undef UPB_INLINE +#undef UPB_API +#undef UPBC_API +#undef UPB_API_INLINE +#undef UPB_API_INLINE_IF_NOT_GCC +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF +#undef UPB_ALIGN_AS +#undef UPB_STATIC_ASSERT +#undef UPB_STATIC_ASSERT_CONCAT +#undef UPB_STATIC_ASSERT_CONCAT_IMPL +#undef UPB_LIKELY +#undef UPB_UNLIKELY +#undef UPB_UNPREDICTABLE +#undef UPB_FORCEINLINE +#undef UPB_NOINLINE +#undef UPB_NORETURN +#undef UPB_PRINTF +#undef UPB_NODEREF +#undef UPB_MAX +#undef UPB_MIN +#undef UPB_UNUSED +#undef UPB_ASSUME +#undef UPB_ASSERT +#undef UPB_UNREACHABLE +#undef UPB_DEFAULT_MAX_BLOCK_SIZE +#undef UPB_SETJMP +#undef UPB_LONGJMP +#undef UPB_PTRADD +#undef UPB_MUSTTAIL +#undef UPB_PRESERVE_MOST +#undef UPB_PRESERVE_NONE +#undef UPB_FASTTABLE_SUPPORTED +#undef UPB_FASTTABLE_MASK +#undef UPB_FASTTABLE +#undef UPB_FASTTABLE_INIT +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN +#undef UPB_HWASAN +#undef UPB_HWASAN_POISON_TAG +#undef UPB_MSAN +#undef UPB_MALLOC_ALIGN +#undef UPB_TSAN +#undef UPB_DEPRECATED +#undef UPB_GNUC_MIN +#undef UPB_DESCRIPTOR_UPB_H_FILENAME +#undef UPB_DESC_MINITABLE +#undef UPB_IS_GOOGLE3 +#undef UPB_ATOMIC +#undef UPB_USE_C11_ATOMICS +#undef UPB_USE_MSC_ATOMICS +#undef UPB_PRIVATE +#undef UPB_ONLYBITS +#undef UPB_LINKARR_DECLARE +#undef UPB_LINKARR_APPEND +#undef UPB_LINKARR_START +#undef UPB_LINKARR_STOP +#undef UPB_FUTURE_BREAKING_CHANGES +#undef UPB_HAS_ATTRIBUTE +#undef UPB_HAS_CPP_ATTRIBUTE +#undef UPB_HAS_BUILTIN +#undef UPB_HAS_EXTENSION +#undef UPB_HAS_FEATURE +#undef UPB_XSAN_MEMBER +#undef UPB_XSAN +#undef UPB_XSAN_STRUCT_SIZE +#undef UPB_ENABLE_REF_CYCLE_CHECKS +#undef UPB_ARM64_ASM +#undef UPB_ARM64_BTI_DEFAULT +#undef UPB_DEPRECATE_AND_INLINE +#undef UPB_MAYBE_ASSUME +#undef UPB_ATTR_CONST diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h new file mode 100755 index 0000000..6719530 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/ruby-upb.h @@ -0,0 +1,18003 @@ +/* Amalgamated source file */ + +/* + * This is where we define internal portability macros used across upb. + * + * All of these macros are undef'd in undef.inc to avoid leaking them to users. + * + * The correct usage is: + * + * #include "upb/foobar.h" + * #include "upb/baz.h" + * + * // MUST be last included header. + * #include "upb/port/def.inc" + * + * // Code for this file. + * // <...> + * + * // Can be omitted for .c files, required for .h. + * #include "upb/port/undef.inc" + * + * This file is private and must not be included by users! + */ + +#if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900)) +#error upb requires C99 or C++17 or MSVC >= 2015. +#endif + +// Portable check for GCC minimum version: +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +#define UPB_GNUC_MIN(x, y) \ + (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y)) +#else +#define UPB_GNUC_MIN(x, y) 0 +#endif + +// Macros for checking for compiler attributes, defined here to avoid the +// problem described in +// https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. +#ifdef __has_attribute +#define UPB_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +#define UPB_HAS_ATTRIBUTE(x) 0 +#endif + +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define UPB_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define UPB_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +// Once in a while we want to use this macro in a C++-only portion of an +// otherwise C-compatible header, so we copy and paste this from ABSL. +#if UPB_HAS_CPP_ATTRIBUTE(deprecated) && UPB_HAS_CPP_ATTRIBUTE(clang::annotate) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated, clang::annotate("inline-me")]] +#elif UPB_HAS_CPP_ATTRIBUTE(deprecated) +#define UPB_DEPRECATE_AND_INLINE() [[deprecated]] +#else +#define UPB_DEPRECATE_AND_INLINE() +#endif + +#ifdef __has_builtin +#define UPB_HAS_BUILTIN(x) __has_builtin(x) +#else +#define UPB_HAS_BUILTIN(x) 0 +#endif + +#ifdef __has_extension +#define UPB_HAS_EXTENSION(x) __has_extension(x) +#else +#define UPB_HAS_EXTENSION(x) 0 +#endif + +#ifdef __has_feature +#define UPB_HAS_FEATURE(x) __has_feature(x) +#else +#define UPB_HAS_FEATURE(x) 0 +#endif + +#include <assert.h> +#include <setjmp.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef UINTPTR_MAX +Error, UINTPTR_MAX is undefined +#endif + +#if UINTPTR_MAX == 0xffffffff +#define UPB_SIZE(size32, size64) size32 +#else +#define UPB_SIZE(size32, size64) size64 +#endif + +/* If we always read/write as a consistent type to each address, this shouldn't + * violate aliasing. + */ +#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs))) + +// A flexible array member may have lower alignment requirements than the struct +// overall - in that case, it can overlap with the trailing padding of the rest +// of the struct, and a naive sizeof(base) + sizeof(flex) * count calculation +// will not take into account that overlap, and allocate more than is required. +#define UPB_SIZEOF_FLEX(type, member, count) \ + UPB_MAX(sizeof(type), offsetof(type, member[count])) + +#define UPB_SIZEOF_FLEX_WOULD_OVERFLOW(type, member, count) \ + (((SIZE_MAX - offsetof(type, member[0])) / \ + (offsetof(type, member[1]) - offsetof(type, member[0]))) < (size_t)count) + +#define UPB_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) + +#define UPB_MAPTYPE_STRING 0 + +// UPB_EXPORT: always generate a public symbol. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_EXPORT __attribute__((visibility("default"))) __attribute__((used)) +#else +#define UPB_EXPORT +#endif + +// UPB_INLINE: inline if possible, emit standalone code if required. +#ifdef __cplusplus +#define UPB_INLINE inline +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_INLINE static __inline__ +#else +#define UPB_INLINE static +#endif + +// UPB_INLINE_IF_NOT_GCC: because gcc can be very noisy at times. +#if defined(__GNUC__) && !defined(__clang__) +#define UPB_INLINE_IF_NOT_GCC static +#else +#define UPB_INLINE_IF_NOT_GCC UPB_INLINE +#endif + +#ifdef UPB_BUILD_API +#define UPB_API UPB_EXPORT +#define UPB_API_INLINE UPB_EXPORT +#else +#define UPB_API +#define UPB_API_INLINE UPB_INLINE +#endif + +#ifdef EXPORT_UPBC +#define UPBC_API UPB_EXPORT +#else +#define UPBC_API +#endif + +#if UPB_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#define UPB_ASAN 1 +#else +#define UPB_ASAN 0 +#endif + +#if UPB_HAS_FEATURE(hwaddress_sanitizer) +#define UPB_HWASAN 1 +#define UPB_HWASAN_POISON_TAG 17 +#define UPB_MALLOC_ALIGN 16 +#else +#define UPB_HWASAN 0 +#define UPB_MALLOC_ALIGN 8 +#endif + +#if UPB_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) +#define UPB_TSAN 1 +#else +#define UPB_TSAN 0 +#endif + +#if UPB_HAS_FEATURE(memory_sanitizer) +#define UPB_MSAN 1 +#else +#define UPB_MSAN 0 +#endif + +// An unfortunate concession to C++17 and MSVC, which don't support zero-sized +// structs. +#if UPB_ASAN || UPB_HWASAN || UPB_TSAN +#define UPB_XSAN_MEMBER upb_Xsan xsan; +#define UPB_XSAN(st) (&(st)->xsan) +#define UPB_XSAN_STRUCT_SIZE 1 +#else +#define UPB_XSAN_MEMBER +#define UPB_XSAN(st) (NULL) +#define UPB_XSAN_STRUCT_SIZE 0 +#endif + +#define UPB_ALIGN_UP(size, align) (((size) + (align) - 1) / (align) * (align)) +#define UPB_ALIGN_DOWN(size, align) ((size) / (align) * (align)) +#define UPB_ALIGN_MALLOC(size) UPB_ALIGN_UP(size, UPB_MALLOC_ALIGN) + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_alignof) || \ + defined(__cplusplus) +#define UPB_ALIGN_OF(type) alignof(type) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_alignof) +#define UPB_ALIGN_OF(type) _Alignof(type) +#elif UPB_GNUC_MIN(2, 95) +#define UPB_ALIGN_OF(type) __alignof__(type) +#elif defined(_MSC_VER) +#define UPB_ALIGN_OF(type) __alignof(type) +#else +#define UPB_ALIGN_OF(type) \ + offsetof( \ + struct { \ + char c; \ + type member; \ + }, \ + member) +#endif + +#ifdef _MSC_VER +// Some versions of our Windows compiler don't support the C11 syntax. +#define UPB_ALIGN_AS(x) __declspec(align(x)) +#elif defined(__GNUC__) +#define UPB_ALIGN_AS(x) __attribute__((aligned(x))) +#else +#define UPB_ALIGN_AS(x) _Alignas(x) +#endif + +#if __STDC_VERSION__ >= 202311L || UPB_HAS_EXTENSION(cxx_static_assert) || \ + defined(__cplusplus) +#define UPB_STATIC_ASSERT(val, msg) static_assert((val), msg) +#elif __STDC_VERSION__ >= 201112L || UPB_HAS_EXTENSION(c_static_assert) || \ + UPB_GNUC_MIN(4, 6) +#define UPB_STATIC_ASSERT(val, msg) _Static_assert((val), msg) +#else +// Unfortunately this hack doesn't work inside struct declarations, but it works +// everywhere else +#define UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) s1##s2 +#define UPB_STATIC_ASSERT_CONCAT(s1, s2) UPB_STATIC_ASSERT_CONCAT_IMPL(s1, s2) +#ifdef __COUNTER__ +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __COUNTER__)[(condition) ? 1 : -1] +#else +#define UPB_STATIC_ASSERT(condition, message) \ + typedef char UPB_STATIC_ASSERT_CONCAT(static_assertion_failure_, \ + __LINE__)[(condition) ? 1 : -1] +#endif +#endif + +// Hints to the compiler about likely/unlikely branches. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_LIKELY(x) __builtin_expect((bool)(x), 1) +#define UPB_UNLIKELY(x) __builtin_expect((bool)(x), 0) +#else +#define UPB_LIKELY(x) (x) +#define UPB_UNLIKELY(x) (x) +#endif + +#if UPB_HAS_BUILTIN(__builtin_expect_with_probability) +#define UPB_UNPREDICTABLE(x) \ + __builtin_expect_with_probability((bool)(x), 1, 0.5) +#else +#define UPB_UNPREDICTABLE(x) (x) +#endif + +// Macros for function attributes on compilers that support them. +#if defined(__GNUC__) || defined(__clang__) +#define UPB_FORCEINLINE __inline__ __attribute__((always_inline)) static +#define UPB_NOINLINE __attribute__((noinline)) +#define UPB_NORETURN __attribute__((__noreturn__)) +#define UPB_PRINTF(str, first_vararg) \ + __attribute__((format(printf, str, first_vararg))) +#elif defined(_MSC_VER) +#define UPB_NOINLINE +#define UPB_FORCEINLINE static +#define UPB_NORETURN __declspec(noreturn) +#define UPB_PRINTF(str, first_vararg) +#else /* !defined(__GNUC__) */ +#define UPB_FORCEINLINE static +#define UPB_NOINLINE +#define UPB_NORETURN +#define UPB_PRINTF(str, first_vararg) +#endif + +#if defined(__clang__) +#define UPB_NODEREF __attribute__((noderef)) +#else +#define UPB_NODEREF +#endif + +#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y)) +#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y)) + +#define UPB_UNUSED(var) (void)(var) + +// UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) \ + if (!(expr)) __builtin_unreachable() +#elif defined _MSC_VER +#define UPB_ASSUME(expr) \ + if (!(expr)) __assume(0) +#else +#define UPB_ASSUME(expr) \ + do { \ + } while (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + +#if UPB_HAS_BUILTIN(__builtin_constant_p) && UPB_HAS_ATTRIBUTE(const) +#define UPB_MAYBE_ASSUME(pred, x) \ + if (__builtin_constant_p(pred) && pred) UPB_ASSUME(x) +#define UPB_ATTR_CONST __attribute__((const)) +#else +#define UPB_MAYBE_ASSUME(pred, x) +#define UPB_ATTR_CONST +#endif + +/* UPB_ASSERT(): in release mode, we use the expression without letting it be + * evaluated. This prevents "unused variable" warnings. */ +#ifdef NDEBUG +#define UPB_ASSERT(expr) \ + do { \ + } while (false && (expr)) +#else +#define UPB_ASSERT(expr) assert(expr) +#endif + +#if !defined(NDEBUG) && !defined(UPB_TSAN) +#define UPB_ENABLE_REF_CYCLE_CHECKS 1 +#else +#define UPB_ENABLE_REF_CYCLE_CHECKS 0 +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + __assume(0); \ + } while (0) +#else +#define UPB_UNREACHABLE() \ + do { \ + assert(0); \ + } while (0) +#endif + +#ifdef __ANDROID__ +#define UPB_DEFAULT_MAX_BLOCK_SIZE 8192 +#else +#define UPB_DEFAULT_MAX_BLOCK_SIZE 32768 +#endif + +/* UPB_SETJMP() / UPB_LONGJMP() */ +// Android uses a custom libc that does not implement all of posix, but it has +// had sigsetjmp/siglongjmp forever on arm and since API 12 on x86. Apple has +// sigsetjmp, but does not define the posix feature test macro. +#if defined(__APPLE__) || defined(_POSIX_C_SOURCE) || defined(__ANDROID__) +// avoid setting/restoring signal mask, which involves costly syscalls +#define UPB_SETJMP(buf) sigsetjmp(buf, 0) +#define UPB_LONGJMP(buf, val) siglongjmp(buf, val) +#elif defined(WASM_WAMR) +#define UPB_SETJMP(buf) 0 +#define UPB_LONGJMP(buf, val) abort() +#else +#define UPB_SETJMP(buf) setjmp(buf) +#define UPB_LONGJMP(buf, val) longjmp(buf, val) +#endif + +#if ((__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)) || \ + UPB_HAS_EXTENSION(c_atomic) || \ + defined(__GNUC__) // GCC supported atomics as an extension before it + // supported __has_extension +#define UPB_USE_C11_ATOMICS +#elif defined(_MSC_VER) +#define UPB_USE_MSC_ATOMICS +#endif + +#if defined(UPB_USE_C11_ATOMICS) +#define UPB_ATOMIC(T) _Atomic(T) +#elif defined(UPB_USE_MSC_ATOMICS) +#define UPB_ATOMIC(T) volatile T +#else +#define UPB_ATOMIC(T) T +#endif + +/* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */ +#define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr)) + +#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only + +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + +/* Configure whether fasttable is switched on or not. *************************/ + +#if UPB_HAS_ATTRIBUTE(musttail) +#define UPB_MUSTTAIL __attribute__((musttail)) +#else +#define UPB_MUSTTAIL +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_most) && !defined(__i386__) +#define UPB_PRESERVE_MOST __attribute__((preserve_most)) +#else +#define UPB_PRESERVE_MOST +#endif + +#if UPB_HAS_ATTRIBUTE(preserve_none) +#define UPB_PRESERVE_NONE __attribute__((preserve_none)) +#else +#define UPB_PRESERVE_NONE +#endif + +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +#define UPB_ARM64_ASM 1 +#else +#define UPB_ARM64_ASM 0 +#endif + +/* When compiling with branch protection, we need to ensure that all branch + * targets in assembly use the appropriate landing pad instruction. These + * instructions are backwards compatible with processors that don't have + * FEAT_BTI and are treated as nops. + */ +#if UPB_ARM64_ASM && defined(__ARM_FEATURE_BTI_DEFAULT) +#if __ARM_FEATURE_BTI_DEFAULT == 1 +#define UPB_ARM64_BTI_DEFAULT 1 +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif +#else +#define UPB_ARM64_BTI_DEFAULT 0 +#endif + +/* This check is not fully robust: it does not require that we have "musttail" + * support available. We need tail calls to avoid consuming arbitrary amounts + * of stack space. + * + * GCC/Clang can mostly be trusted to generate tail calls as long as + * optimization is enabled, but, debug builds will not generate tail calls + * unless "musttail" is available. + * + * We should probably either: + * 1. require that the compiler supports musttail. + * 2. add some fallback code for when musttail isn't available (ie. return + * instead of tail calling). This is safe and portable, but this comes at + * a CPU cost. + */ +#if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__) +#define UPB_FASTTABLE_SUPPORTED 1 +#else +#define UPB_FASTTABLE_SUPPORTED 0 +#endif + +/* define UPB_ENABLE_FASTTABLE to force fast table support. + * This is useful when we want to ensure we are really getting fasttable, + * for example for testing or benchmarking. */ +#if defined(UPB_ENABLE_FASTTABLE) +#if !UPB_FASTTABLE_SUPPORTED +#error fasttable is x86-64/ARM64 only and requires GCC or Clang. +#endif +#define UPB_FASTTABLE 1 +/* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible. + * This is useful for releasing code that might be used on multiple platforms, + * for example the PHP or Ruby C extensions. */ +#elif defined(UPB_TRY_ENABLE_FASTTABLE) +#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#else +#define UPB_FASTTABLE 0 +#endif + +/* UPB_FASTTABLE_INIT() allows protos compiled for fasttable to gracefully + * degrade to non-fasttable if the runtime or platform do not support it. */ +#if !UPB_FASTTABLE +#define UPB_FASTTABLE_INIT(...) +#define UPB_FASTTABLE_MASK(mask) -1 +#else +#define UPB_FASTTABLE_INIT(...) __VA_ARGS__ +#define UPB_FASTTABLE_MASK(mask) mask +#endif + +#undef UPB_FASTTABLE_SUPPORTED + +#if defined(__cplusplus) +#if defined(__clang__) || UPB_GNUC_MIN(6, 0) +// https://gcc.gnu.org/gcc-6/changes.html +#define UPB_DEPRECATED [[deprecated]] +#else +#define UPB_DEPRECATED +#endif +#else +#define UPB_DEPRECATED +#endif + +#if defined(UPB_IS_GOOGLE3) && \ + (!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0) +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_IS_GOOGLE3) && defined(UPB_BOOTSTRAP_STAGE) && \ + UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) proto2__##sym##_msg_init() +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() +#else +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init +#endif + +#undef UPB_IS_GOOGLE3 + +#ifdef __clang__ +#define UPB_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address"))) +#else +#define UPB_NO_SANITIZE_ADDRESS +#endif + +#if defined(__GNUC__) && (defined(__clang__) || UPB_GNUC_MIN(11, 0)) +#define UPB_RETAIN __attribute__((retain)) +#else +#define UPB_RETAIN +#endif + +// Linker arrays combine elements from multiple translation units into a single +// array that can be iterated over at runtime. +// +// It is an alternative to pre-main "registration" functions. +// +// Usage: +// +// // In N translation units. +// UPB_LINKARR_APPEND(foo_array) static int elems[3] = {1, 2, 3}; +// +// // At runtime: +// UPB_LINKARR_DECLARE(foo_array, int); +// +// void f() { +// const int* start = UPB_LINKARR_START(foo_array); +// const int* stop = UPB_LINKARR_STOP(foo_array); +// for (const int* p = start; p < stop; p++) { +// // Windows can introduce zero padding, so we have to skip zeroes. +// if (*p != 0) { +// vec.push_back(*p); +// } +// } +// } + +#if defined(__GNUC__) && !defined(__clang__) +// GCC can't handle mismatched retain attributes in the same section: +// https://github.com/protocolbuffers/protobuf/issues/26385 +// To work around this, we retain all linker array elements, even though this +// effectively disables tree-shaking of unused extensions when using GCC. +#define UPB_LINKARR_ATTR UPB_RETAIN +#else +#define UPB_LINKARR_ATTR +#endif + +#define UPB_LINKARR_SENTINEL UPB_RETAIN __attribute__((weak, used)) + +#if defined(__ELF__) || defined(__wasm__) + +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(__MACH__) + +/* As described in: https://stackoverflow.com/a/22366882 */ +#define UPB_LINKARR_APPEND(name) \ + __attribute__(( \ + section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS +#define UPB_LINKARR_DECLARE(name, type) \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ + UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#elif defined(_MSC_VER) + +/* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ +#define UPB_STRINGIFY_INTERNAL(x) #x +#define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) +#define UPB_CONCAT(a, b, c) a##b##c +#define UPB_LINKARR_NAME(name, index) \ + UPB_STRINGIFY(UPB_CONCAT(la_, name, index)) +#define UPB_LINKARR_APPEND(name) \ + __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $j))) +// clang-format off +#define UPB_LINKARR_DECLARE(name, type) \ + __pragma(message(UPB_LINKARR_NAME(name, $j))) \ + __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ + __pragma(section(UPB_LINKARR_NAME(name, $z), read)) \ + __declspec(allocate(UPB_LINKARR_NAME(name, $a)), selectany) \ + type __start_linkarr_##name; \ + __declspec(allocate(UPB_LINKARR_NAME(name, $z)), selectany) \ + type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ + __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} +// clang-format on +#define UPB_LINKARR_START(name) (&__start_linkarr_##name) +#define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) + +#else + +// Linker arrays are not supported on this platform. Make macros no-ops. +#define UPB_LINKARR_APPEND(name) +#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_START(name) (NULL) +#define UPB_LINKARR_STOP(name) (NULL) + +#endif + +// Workaround for https://github.com/llvm/llvm-project/issues/167577 until it's +// fixed. Some function must exist for the constructor to work properly. +// TODO Remove this or gate it on a future version of clang. +#if defined(__clang__) && defined(__arm__) +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((used, visibility("hidden"))) void UPB_PRIVATE(unique_name)( \ + void) {} +#else +#define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) +#endif + +#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) +#define UPB_CONSTRUCTOR(name, unique_name) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ + name)(void) +#elif defined(_MSC_VER) +/* + * See: https://stackoverflow.com/questions/1113409 + * + * The /include pragma suggested in the link above doesn't work in our case + * because it requires globally unique names. We need a different solution + * to prevent optimizers from removing the constructor. Our solution is to + * create a dummy exported weak symbol that prevent this stripping. + */ +#pragma section(".CRT$XCT", read) +#define UPB_CONSTRUCTOR(name, unique_name) \ + static void __cdecl UPB_PRIVATE(name)(void); \ + __declspec(allocate(".CRT$XCT"), selectany) void( \ + __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ + __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ + &UPB_PRIVATE(name##_); \ + static void __cdecl UPB_PRIVATE(name)(void) + +#else +// No constructor support, nothing we can do except not break builds. +#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#endif + +// +// Weak alias platform support. Theoretically this should be possible to do with +// only C using attributes like __attribute__((weak, alias("foo"))), but +// Clang doesn't support this properly on macOS. So we have to use assembly. +#if defined(__APPLE__) + +// TODO: once https://github.com/llvm/llvm-project/issues/167262 is fixed +// in the LLVM linker, we should have all weak variables point to a single +// "default" empty MiniTable instead of having each leaf define its own, like +// we do with ELF below. This will reduce binary size if many messages are tree +// shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) \ + __attribute__((weak)) const upb_MiniTable name = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to; \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); \ + __asm__(".weak_definition _" #to); +#define UPB_STRONG_ALIAS(type, from, to) \ + __asm__(".globl _" #to); \ + __asm__(".private_extern _" #to); \ + __asm__(".set _" #to ", _" #from); + +#elif defined(__ELF__) + +// On ELF, weak aliases work properly, so we can have all weak MiniTables point +// to the same empty singleton MiniTable. This reduces code size if many +// MiniTables are tree shaken. +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ + __attribute__((weak)) \ + const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ + .UPB_PRIVATE(fields) = NULL, \ + .UPB_PRIVATE(size) = sizeof(struct upb_Message), \ + .UPB_PRIVATE(field_count) = 0, \ + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, \ + .UPB_PRIVATE(dense_below) = 0, \ + .UPB_PRIVATE(table_mask) = -1, \ + .UPB_PRIVATE(required_count) = 0, \ + }; +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) \ + extern type to \ + __attribute__((weak, alias("kUpb_WeakSingletonPlaceholderMiniTable"))); +#define UPB_STRONG_ALIAS(type, from, to) \ + extern type to __attribute__((alias(#from))); + +#else +#define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() +#define UPB_WEAK_PLACEHOLDER_MINITABLE(name) +#define UPB_WEAK_ALIAS(type, from, to) weak_alias_not_supported_on_this_platform +#define UPB_STRONG_ALIAS(type, from, to) \ + strong_alias_not_supported_on_this_platform +#endif + +// Future versions of upb will include breaking changes to some APIs. +// This macro can be set to enable these API changes ahead of time, so that +// user code can be updated before upgrading versions of protobuf. +#ifdef UPB_FUTURE_BREAKING_CHANGES + +#endif + +#ifndef UPB_GENERATED_CODE_SUPPORT_H_ +#define UPB_GENERATED_CODE_SUPPORT_H_ + +// This is a bit awkward; we want to conditionally include the fast decoder, +// but we generally don't let macros like UPB_FASTTABLE leak into user code. +// We can't #include "decode_fast.h" inside the port/def.inc, because the +// inc files strictly prohibit recursive inclusion, and decode_fast.h includes +// port/def.inc. So instead we use this two-part dance to conditionally include +// decode_fast.h. +#if UPB_FASTTABLE +#define UPB_INCLUDE_FAST_DECODE +#endif + +// IWYU pragma: begin_exports + +#ifndef UPB_BASE_UPCAST_H_ +#define UPB_BASE_UPCAST_H_ + +// Must be last. + +// This macro provides a way to upcast message pointers in a way that is +// somewhat more bulletproof than blindly casting a pointer. Example: +// +// typedef struct { +// upb_Message UPB_PRIVATE(base); +// } pkg_FooMessage; +// +// void f(pkg_FooMessage* msg) { +// upb_Decode(UPB_UPCAST(msg), ...); +// } + +#define UPB_UPCAST(x) (&(x)->base##_dont_copy_me__upb_internal_use_only) + + +#endif /* UPB_BASE_UPCAST_H_ */ + +#ifndef UPB_MESSAGE_ACCESSORS_H_ +#define UPB_MESSAGE_ACCESSORS_H_ + +#include <stdint.h> + +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ + +#include <string.h> + +// Must be last. + +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return (a.size == b.size) && (!a.size || !memcmp(a.data, b.data, a.size)); +} + +// Compares StringViews following strcmp rules. +// Please note this comparison is neither unicode nor locale aware. +UPB_INLINE int upb_StringView_Compare(upb_StringView a, upb_StringView b) { + int result = memcmp(a.data, b.data, UPB_MIN(a.size, b.size)); + if (result != 0) return result; + if (a.size < b.size) { + return -1; + } else if (a.size > b.size) { + return 1; + } else { + return 0; + } +} + +// LINT.ThenChange( +// GoogleInternalName1, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string, +// //depot/google3/third_party/upb/bits/typescript/string_view.ts +// ) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_STRING_VIEW_H_ */ + +/* upb_Arena is a specific allocator implementation that uses arena allocation. + * The user provides an allocator that will be used to allocate the underlying + * arena blocks. Arenas by nature do not require the individual allocations + * to be freed. However the Arena does allow users to register cleanup + * functions that will run when the arena is destroyed. + * + * A upb_Arena is *not* thread-safe, although some functions related to its + * managing its lifetime are, and are documented as such. + * + * You could write a thread-safe arena allocator that satisfies the + * upb_alloc interface, but it would not be as efficient for the + * single-threaded case. */ + +#ifndef UPB_MEM_ARENA_H_ +#define UPB_MEM_ARENA_H_ + +#include <stddef.h> +#include <stdint.h> + + +#ifndef UPB_MEM_ALLOC_H_ +#define UPB_MEM_ALLOC_H_ + +#include <stddef.h> + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct upb_alloc upb_alloc; + +/* A combined `malloc()`/`free()` function. + * If `size` is 0 then the function acts like `free()`, otherwise it acts like + * `realloc()`. Only `oldsize` bytes from a previous allocation are + * preserved. If `actual_size` is not null and the allocator supports it, the + * actual size of the resulting allocation is stored in `actual_size`. If + * `actual_size` is not null, you must zero out the memory pointed to by + * `actual_size` before calling. */ +typedef void* upb_alloc_func(upb_alloc* alloc, void* ptr, size_t oldsize, + size_t size, size_t* actual_size); + +/* A upb_alloc is a possibly-stateful allocator object. + * + * It could either be an arena allocator (which doesn't require individual + * `free()` calls) or a regular `malloc()` (which does). The client must + * therefore free memory unless it knows that the allocator is an arena + * allocator. */ +struct upb_alloc { + upb_alloc_func* func; +}; + +UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) { + UPB_ASSERT(alloc); + return alloc->func(alloc, NULL, 0, size, NULL); +} + +typedef struct { + void* p; + size_t n; +} upb_SizedPtr; + +UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) { + UPB_ASSERT(alloc); + upb_SizedPtr result; + result.n = 0; + result.p = alloc->func(alloc, NULL, 0, size, &result.n); + result.n = result.p != NULL ? UPB_MAX(result.n, size) : 0; + return result; +} + +UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize, + size_t size) { + UPB_ASSERT(alloc); + return alloc->func(alloc, ptr, oldsize, size, NULL); +} + +UPB_INLINE void upb_free(upb_alloc* alloc, void* ptr) { + UPB_ASSERT(alloc); + alloc->func(alloc, ptr, 0, 0, NULL); +} + +UPB_INLINE void upb_free_sized(upb_alloc* alloc, void* ptr, size_t size) { + UPB_ASSERT(alloc); + alloc->func(alloc, ptr, size, 0, NULL); +} + +// The global allocator used by upb. Uses the standard malloc()/free(). + +extern upb_alloc upb_alloc_global; + +/* Functions that hard-code the global malloc. + * + * We still get benefit because we can put custom logic into our global + * allocator, like injecting out-of-memory faults in debug/testing builds. */ + +UPB_INLINE void* upb_gmalloc(size_t size) { + return upb_malloc(&upb_alloc_global, size); +} + +UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, size_t size) { + return upb_realloc(&upb_alloc_global, ptr, oldsize, size); +} + +UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MEM_ALLOC_H_ */ + +#ifndef UPB_MEM_INTERNAL_ARENA_H_ +#define UPB_MEM_INTERNAL_ARENA_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +#ifndef UPB_PORT_SANITIZERS_H_ +#define UPB_PORT_SANITIZERS_H_ + +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> + +// Must be last. + +// Must be inside def.inc/undef.inc +#if UPB_HWASAN +#include <sanitizer/hwasan_interface.h> +#endif + +#if UPB_MSAN +#include <sanitizer/msan_interface.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// UPB_ARENA_SIZE_HACK depends on this struct having size 1. +typedef struct { + uint8_t state; +} upb_Xsan; + +UPB_INLINE uint8_t _upb_Xsan_NextTag(upb_Xsan *xsan) { +#if UPB_HWASAN + xsan->state++; + if (xsan->state <= UPB_HWASAN_POISON_TAG) { + xsan->state = UPB_HWASAN_POISON_TAG + 1; + } + return xsan->state; +#else + UPB_UNUSED(xsan); + return 0; +#endif +} + +enum { +#if UPB_ASAN + UPB_PRIVATE(kUpb_Asan_GuardSize) = 32, +#else + UPB_PRIVATE(kUpb_Asan_GuardSize) = 0, +#endif +}; + +UPB_INLINE uint8_t UPB_PRIVATE(_upb_Xsan_GetTag)(const void *addr) { +#if UPB_HWASAN + return __hwasan_get_tag_from_pointer(addr); +#else + UPB_UNUSED(addr); + return 0; +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_Init)(upb_Xsan *xsan) { +#if UPB_HWASAN || UPB_TSAN + xsan->state = 0; +#else + UPB_UNUSED(xsan); +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_MarkInitialized)(void* addr, size_t size) { +#if UPB_HAS_FEATURE(memory_sanitizer) + if (size) { + __msan_unpoison(addr, size); + } +#else + UPB_UNUSED(addr); + UPB_UNUSED(size); +#endif +} + +// Marks the given region as poisoned, meaning that it is not accessible until +// it is unpoisoned. +UPB_INLINE void UPB_PRIVATE(upb_Xsan_PoisonRegion)(const void *addr, + size_t size) { +#if UPB_ASAN + void __asan_poison_memory_region(void const volatile *addr, size_t size); + __asan_poison_memory_region(addr, size); +#elif UPB_HWASAN + __hwasan_tag_memory(addr, UPB_HWASAN_POISON_TAG, UPB_ALIGN_MALLOC(size)); +#else + UPB_UNUSED(addr); + UPB_UNUSED(size); +#endif +} + +UPB_INLINE void *UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(void *addr, size_t size, + uint8_t tag) { +#if UPB_ASAN + UPB_UNUSED(tag); + void __asan_unpoison_memory_region(void const volatile *addr, size_t size); + __asan_unpoison_memory_region(addr, size); + return addr; +#elif UPB_HWASAN + __hwasan_tag_memory(addr, tag, UPB_ALIGN_MALLOC(size)); + return __hwasan_tag_pointer(addr, tag); +#else + UPB_UNUSED(size); + UPB_UNUSED(tag); + + // `addr` is the pointer that will be returned from arena alloc/realloc + // functions. In this code-path we know it must be non-NULL, but the compiler + // doesn't know this unless we add a UPB_ASSUME() annotation. + // + // This will let the optimizer optimize away NULL-checks if it can see that + // this path was taken. + UPB_ASSUME(addr); + return addr; +#endif +} + +// Allows users to read and write to the given region, which will be considered +// distinct from other regions and may only be accessed through the returned +// pointer. +// +// `addr` must be aligned to the malloc alignment. Size may be unaligned, +// and with ASAN we can respect `size` precisely, but with HWASAN we must +// round `size` up to the next multiple of the malloc alignment, so the caller +// must guarantee that rounding up `size` will not cause overlap with other +// regions. +UPB_INLINE void *UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(upb_Xsan *xsan, + void *addr, + size_t size) { + return UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(addr, size, + _upb_Xsan_NextTag(xsan)); +} + +// Resizes the given region to a new size, *without* invalidating any existing +// pointers to the region. +// +// `tagged_addr` must be a pointer that was previously returned from +// `upb_Xsan_NewUnpoisonedRegion`. `old_size` must be the size that was +// originally passed to `upb_Xsan_NewUnpoisonedRegion`. +UPB_INLINE void *UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(void *tagged_addr, + size_t old_size, + size_t new_size) { + UPB_PRIVATE(upb_Xsan_PoisonRegion)(tagged_addr, old_size); + return UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)( + tagged_addr, new_size, UPB_PRIVATE(_upb_Xsan_GetTag)(tagged_addr)); +} + +// Compares two pointers and returns true if they are equal. This returns the +// correct result even if one or both of the pointers are tagged. +UPB_INLINE bool UPB_PRIVATE(upb_Xsan_PtrEq)(const void *a, const void *b) { +#if UPB_HWASAN + return __hwasan_tag_pointer(a, 0) == __hwasan_tag_pointer(b, 0); +#else + return a == b; +#endif +} + +// These annotations improve TSAN's ability to detect data races. By +// proactively accessing a non-atomic variable at the point where it is +// "logically" accessed, we can trigger TSAN diagnostics that might have +// otherwise been masked by subsequent atomic operations. + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_AccessReadOnly)(upb_Xsan *xsan) { +#if UPB_TSAN + // For performance we avoid using a volatile variable. + __asm__ volatile("" ::"r"(xsan->state)); +#else + UPB_UNUSED(xsan); +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_Xsan_AccessReadWrite)(upb_Xsan *xsan) { +#if UPB_TSAN + // For performance we avoid using a volatile variable. + __asm__ volatile("" : "+r"(xsan->state)); +#else + UPB_UNUSED(xsan); +#endif +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_PORT_SANITIZERS_H_ + +// Must be last. + +// This is QUITE an ugly hack, which specifies the number of pointers needed +// to equal (or exceed) the storage required for one upb_Arena. +// +// We need this because the decoder inlines a upb_Arena for performance but +// the full struct is not visible outside of arena.c. Yes, I know, it's awful. +#ifndef NDEBUG +#define UPB_ARENA_BASE_SIZE_HACK 10 +#else +#define UPB_ARENA_BASE_SIZE_HACK 9 +#endif + +#define UPB_ARENA_SIZE_HACK \ + (sizeof(void*) * (UPB_ARENA_BASE_SIZE_HACK + (UPB_XSAN_STRUCT_SIZE * 2))) + \ + (sizeof(uint32_t) * 2) + +// LINT.IfChange(upb_Arena) + +struct upb_Arena { + char* UPB_ONLYBITS(ptr); + const UPB_NODEREF char* UPB_ONLYBITS(end); + UPB_XSAN_MEMBER +}; + +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts:upb_Arena) + +#ifdef __cplusplus +extern "C" { +#endif + +void UPB_PRIVATE(_upb_Arena_SwapIn)(struct upb_Arena* des, + const struct upb_Arena* src); +void UPB_PRIVATE(_upb_Arena_SwapOut)(struct upb_Arena* des, + const struct upb_Arena* src); + +UPB_INLINE size_t UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) { + return (size_t)(a->UPB_ONLYBITS(end) - a->UPB_ONLYBITS(ptr)); +} + +UPB_INLINE size_t UPB_PRIVATE(_upb_Arena_AllocSpan)(size_t size) { + return UPB_ALIGN_MALLOC(size) + UPB_PRIVATE(kUpb_Asan_GuardSize); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)( + const struct upb_Arena* a, void* ptr, size_t size) { + return UPB_PRIVATE(upb_Xsan_PtrEq)( + (char*)ptr + UPB_PRIVATE(_upb_Arena_AllocSpan)(size), + a->UPB_ONLYBITS(ptr)); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_Arena_IsAligned)(const void* ptr) { + return (uintptr_t)ptr % UPB_MALLOC_ALIGN == 0; +} + +UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + + size_t span = UPB_PRIVATE(_upb_Arena_AllocSpan)(size); + + if (UPB_UNLIKELY(UPB_PRIVATE(_upb_ArenaHas)(a) < span)) { + void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(struct upb_Arena * a, size_t size); + return UPB_PRIVATE(_upb_Arena_SlowMalloc)(a, span); + } + + // We have enough space to do a fast malloc. + void* ret = a->UPB_ONLYBITS(ptr); + a->UPB_ONLYBITS(ptr) += span; + UPB_ASSERT(UPB_PRIVATE(_upb_Arena_IsAligned)(ret)); + UPB_ASSERT(UPB_PRIVATE(_upb_Arena_IsAligned)(a->UPB_ONLYBITS(ptr))); + + return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size); +} + +UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr, + size_t oldsize, size_t size) { + UPB_ASSERT(ptr); + UPB_ASSERT(size <= oldsize); + + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(ptr, oldsize, size); + + if (UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)(a, ptr, oldsize)) { + // We can reclaim some memory. + a->UPB_ONLYBITS(ptr) -= UPB_ALIGN_MALLOC(oldsize) - UPB_ALIGN_MALLOC(size); + } else { + // We can't reclaim any memory, but we need to verify that `ptr` really + // does represent the most recent allocation. +#ifndef NDEBUG + bool _upb_Arena_WasLastAlloc(struct upb_Arena * a, void* ptr, + size_t oldsize); + UPB_ASSERT(_upb_Arena_WasLastAlloc(a, ptr, oldsize)); +#endif + } +} + +UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr, + size_t oldsize, size_t size) { + UPB_ASSERT(ptr); + UPB_ASSERT(size > oldsize); + + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + size_t extend = UPB_ALIGN_MALLOC(size) - UPB_ALIGN_MALLOC(oldsize); + + if (UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)(a, ptr, oldsize) && + UPB_PRIVATE(_upb_ArenaHas)(a) >= extend) { + a->UPB_ONLYBITS(ptr) += extend; + UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(ptr, oldsize, size); + return true; + } + + return false; +} + +UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, void* ptr, + size_t oldsize, size_t size) { + UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); + + void* ret; + + if (ptr && (size <= oldsize || upb_Arena_TryExtend(a, ptr, oldsize, size))) { + // We can extend or shrink in place. + if (size <= oldsize && + UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)(a, ptr, oldsize)) { + upb_Arena_ShrinkLast(a, ptr, oldsize, size); + } + ret = ptr; + } else { + // We need to copy into a new allocation. + ret = upb_Arena_Malloc(a, size); + if (ret && oldsize > 0) { + memcpy(ret, ptr, UPB_MIN(oldsize, size)); + } + } + + if (ret) { + // We want to invalidate pointers to the old region if hwasan is enabled, so + // we poison and unpoison even if ptr == ret. However, if reallocation fails + // we do not want to poison the old memory, or attempt to poison null. + UPB_PRIVATE(upb_Xsan_PoisonRegion)(ptr, oldsize); + return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size); + } + return ret; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MEM_INTERNAL_ARENA_H_ */ + +// Must be last. + +typedef struct upb_Arena upb_Arena; + +typedef void upb_AllocCleanupFunc(upb_alloc* alloc); + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates an arena from the given initial block (if any -- mem may be NULL). If +// an initial block is specified, the arena's lifetime cannot be extended by +// |upb_Arena_IncRefFor| or |upb_Arena_Fuse|. Additional blocks will be +// allocated from |alloc|. If |alloc| is NULL, this is a fixed-size arena and +// cannot grow. If an initial block is specified, |n| is its length; if there is +// no initial block, |n| is a hint of the size that should be allocated for the +// first block of the arena, such that `upb_Arena_Malloc(hint)` will not require +// another call to |alloc|. +UPB_API upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc); + +UPB_API void upb_Arena_Free(upb_Arena* a); +// Sets the cleanup function for the upb_alloc used by the arena. Only one +// cleanup function can be set, which will be called after all blocks are +// freed. +UPB_API void upb_Arena_SetAllocCleanup(upb_Arena* a, + upb_AllocCleanupFunc* func); + +// Fuses the lifetime of two arenas, such that no arenas that have been +// transitively fused together will be freed until all of them have reached a +// zero refcount. This operation is safe to use concurrently from multiple +// threads. +UPB_API bool upb_Arena_Fuse(const upb_Arena* a, const upb_Arena* b); + +// This operation is safe to use concurrently from multiple threads. +UPB_API bool upb_Arena_IsFused(const upb_Arena* a, const upb_Arena* b); + +// Returns the upb_alloc used by the arena. +UPB_API upb_alloc* upb_Arena_GetUpbAlloc(upb_Arena* a); + +// This operation is safe to use concurrently from multiple threads. +bool upb_Arena_IncRefFor(const upb_Arena* a, const void* owner); +// This operation is safe to use concurrently from multiple threads. +void upb_Arena_DecRefFor(const upb_Arena* a, const void* owner); + +// Creates a reference between the arenas `from` and `to`, guaranteeing that +// the latter will not be freed until `from` is freed. +// +// Users must avoid all of the following error conditions, which will be +// checked in debug mode but are UB in opt: +// +// - Creating reference cycles between arenas. +// - Creating a reference between two arenas that are fused, either now +// or in the future. +// +// Creating a reference multiple times between the same two arenas is not UB but +// is considered wasteful and may be disallowed in the future. +// +// Note that fuses can participate in reference cycles. The following set of +// calls creates a cycle A -> B -> C -> A +// Fuse(A, B); +// Ref(B, C); +// Ref(C, A); +// +// From this perspective, the second rule is just a special-case of the first. +// This set of calls is disallowed because it is effectively creating a +// cycle A -> B -> A +// Fuse(A, B); +// Ref(B, A); +// +// Fuse is special because it creates what is effectively a bidirectional +// ref, but it is not considered a cycle and will be collected correctly. +// +// Note that `from` is not `const`, so it may not be called concurrently +// with any other function on `from`. +// +// Returns whether the reference was created successfully. +bool upb_Arena_RefArena(upb_Arena* from, const upb_Arena* to); + +#ifndef NDEBUG +// Returns true if upb_Arena_RefArena(from, to) was previously called. +// Note that this does not take fuses into account, and it does not follow +// chains of references; it must have been these two arenas exactly that +// created a reference. +bool upb_Arena_HasRef(const upb_Arena* from, const upb_Arena* to); +#endif + +// This operation is safe to use concurrently from multiple threads. +uintptr_t upb_Arena_SpaceAllocated(const upb_Arena* a, size_t* fused_count); +// This operation is safe to use concurrently from multiple threads. +uint32_t upb_Arena_DebugRefCount(const upb_Arena* a); + +#if UPB_ENABLE_REF_CYCLE_CHECKS +// Returns true if there is a chain of arena refs that spans `from` -> `to`. +// Fused arenas are taken into account; for example, this series of calls +// will cause the function to return true: +// +// 1. upb_Arena_Fuse(a, b) +// 2. upb_Arena_RefArena(from, a) +// 3. upb_Arena_RefArena(b, to) +// +// However this function does not return true if `from` and `to` are directly +// fused. +bool upb_Arena_HasRefChain(const upb_Arena* from, const upb_Arena* to); +#endif + +UPB_API_INLINE upb_Arena* upb_Arena_New(void) { + return upb_Arena_Init(NULL, 0, &upb_alloc_global); +} + +UPB_API_INLINE upb_Arena* upb_Arena_NewSized(size_t size_hint) { + return upb_Arena_Init(NULL, size_hint, &upb_alloc_global); +} + +UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size); + +UPB_API_INLINE void* upb_Arena_Realloc(upb_Arena* a, void* ptr, size_t oldsize, + size_t size); + +static const size_t UPB_PRIVATE(kUpbDefaultMaxBlockSize) = + UPB_DEFAULT_MAX_BLOCK_SIZE; + +// Sets the maximum block size for all arenas. This is a global configuration +// setting that will affect all existing and future arenas. If +// upb_Arena_Malloc() is called with a size larger than this, we will exceed +// this size and allocate a larger block. +// +// This API is meant for experimentation only. It will likely be removed in +// the future. +// This operation is safe to use concurrently from multiple threads. +void upb_Arena_SetMaxBlockSize(size_t max); + +// Shrinks the last alloc from arena. +// REQUIRES: (ptr, oldsize) was the last malloc/realloc from this arena. +// We could also add a upb_Arena_TryShrinkLast() which is simply a no-op if +// this was not the last alloc. +UPB_API_INLINE void upb_Arena_ShrinkLast(upb_Arena* a, void* ptr, + size_t oldsize, size_t size); + +// Attempts to extend the given alloc from arena, in place. Is generally +// only likely to succeed for the most recent allocation from this arena. If it +// succeeds, returns true and `ptr`'s allocation is now `size` rather than +// `oldsize`. Returns false if the allocation cannot be extended; `ptr`'s +// allocation is unmodified. See also upb_Arena_Realloc. +// REQUIRES: `size > oldsize`; to shrink, use `upb_Arena_Realloc` or +// `upb_Arena_ShrinkLast`. +UPB_API_INLINE bool upb_Arena_TryExtend(upb_Arena* a, void* ptr, size_t oldsize, + size_t size); + +#ifdef UPB_TRACING_ENABLED +void upb_Arena_SetTraceHandler(void (*initArenaTraceHandler)(const upb_Arena*, + size_t size), + void (*fuseArenaTraceHandler)(const upb_Arena*, + const upb_Arena*), + void (*freeArenaTraceHandler)(const upb_Arena*)); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MEM_ARENA_H_ */ + +#ifndef UPB_MESSAGE_ARRAY_H_ +#define UPB_MESSAGE_ARRAY_H_ + +#include <stddef.h> + + +#ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ +#define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ + +// Must be last. + +// The types a field can have. Note that this list is not identical to the +// types defined in descriptor.proto, which gives INT32 and SINT32 separate +// types (we distinguish the two with the "integer encoding" enum below). +// This enum is an internal convenience only and has no meaning outside of upb. +typedef enum { + kUpb_CType_Bool = 1, + kUpb_CType_Float = 2, + kUpb_CType_Int32 = 3, + kUpb_CType_UInt32 = 4, + kUpb_CType_Enum = 5, // Enum values are int32. TODO: rename + kUpb_CType_Message = 6, + kUpb_CType_Double = 7, + kUpb_CType_Int64 = 8, + kUpb_CType_UInt64 = 9, + kUpb_CType_String = 10, + kUpb_CType_Bytes = 11 +} upb_CType; + +// The repeated-ness of each field; this matches descriptor.proto. +typedef enum { + kUpb_Label_Optional = 1, + kUpb_Label_Required = 2, + kUpb_Label_Repeated = 3 +} upb_Label; + +// Descriptor types, as defined in descriptor.proto. +typedef enum { + kUpb_FieldType_Double = 1, + kUpb_FieldType_Float = 2, + kUpb_FieldType_Int64 = 3, + kUpb_FieldType_UInt64 = 4, + kUpb_FieldType_Int32 = 5, + kUpb_FieldType_Fixed64 = 6, + kUpb_FieldType_Fixed32 = 7, + kUpb_FieldType_Bool = 8, + kUpb_FieldType_String = 9, + kUpb_FieldType_Group = 10, + kUpb_FieldType_Message = 11, + kUpb_FieldType_Bytes = 12, + kUpb_FieldType_UInt32 = 13, + kUpb_FieldType_Enum = 14, + kUpb_FieldType_SFixed32 = 15, + kUpb_FieldType_SFixed64 = 16, + kUpb_FieldType_SInt32 = 17, + kUpb_FieldType_SInt64 = 18, +} upb_FieldType; + +#define kUpb_FieldType_SizeOf 19 + +#ifdef __cplusplus +extern "C" { +#endif + +// Convert from upb_FieldType to upb_CType +UPB_INLINE upb_CType upb_FieldType_CType(upb_FieldType field_type) { + static const upb_CType c_type[] = { + kUpb_CType_Double, // kUpb_FieldType_Double + kUpb_CType_Float, // kUpb_FieldType_Float + kUpb_CType_Int64, // kUpb_FieldType_Int64 + kUpb_CType_UInt64, // kUpb_FieldType_UInt64 + kUpb_CType_Int32, // kUpb_FieldType_Int32 + kUpb_CType_UInt64, // kUpb_FieldType_Fixed64 + kUpb_CType_UInt32, // kUpb_FieldType_Fixed32 + kUpb_CType_Bool, // kUpb_FieldType_Bool + kUpb_CType_String, // kUpb_FieldType_String + kUpb_CType_Message, // kUpb_FieldType_Group + kUpb_CType_Message, // kUpb_FieldType_Message + kUpb_CType_Bytes, // kUpb_FieldType_Bytes + kUpb_CType_UInt32, // kUpb_FieldType_UInt32 + kUpb_CType_Enum, // kUpb_FieldType_Enum + kUpb_CType_Int32, // kUpb_FieldType_SFixed32 + kUpb_CType_Int64, // kUpb_FieldType_SFixed64 + kUpb_CType_Int32, // kUpb_FieldType_SInt32 + kUpb_CType_Int64, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return c_type[field_type - 1]; +} + +UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType field_type) { + // clang-format off + const unsigned kUnpackableTypes = + (1 << kUpb_FieldType_String) | + (1 << kUpb_FieldType_Bytes) | + (1 << kUpb_FieldType_Message) | + (1 << kUpb_FieldType_Group); + // clang-format on + return (1 << field_type) & ~kUnpackableTypes; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_ARRAY_H_ +#define UPB_MESSAGE_INTERNAL_ARRAY_H_ + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +#define _UPB_ARRAY_MASK_IMM 0x4 // Frozen/immutable bit. +#define _UPB_ARRAY_MASK_LG2 0x3 // Encoded elem size. +#define _UPB_ARRAY_MASK_ALL (_UPB_ARRAY_MASK_IMM | _UPB_ARRAY_MASK_LG2) + +#ifdef __cplusplus +extern "C" { +#endif + +// LINT.IfChange(upb_Array) + +// Our internal representation for repeated fields. +struct upb_Array { + // This is a tagged pointer. Bits #0 and #1 encode the elem size as follows: + // 0 maps to elem size 1 + // 1 maps to elem size 4 + // 2 maps to elem size 8 + // 3 maps to elem size 16 + // + // Bit #2 contains the frozen/immutable flag. + uintptr_t UPB_ONLYBITS(data); + + size_t UPB_ONLYBITS(size); // The number of elements in the array. + size_t UPB_PRIVATE(capacity); // Allocated storage. Measured in elements. +}; + +UPB_INLINE void UPB_PRIVATE(_upb_Array_ShallowFreeze)(struct upb_Array* arr) { + arr->UPB_ONLYBITS(data) |= _UPB_ARRAY_MASK_IMM; +} + +UPB_API_INLINE bool upb_Array_IsFrozen(const struct upb_Array* arr) { + return (arr->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_IMM) != 0; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Array_SetTaggedPtr)(struct upb_Array* array, + void* data, size_t lg2) { + UPB_ASSERT(lg2 != 1); + UPB_ASSERT(lg2 <= 4); + const size_t bits = lg2 - (lg2 != 0); + array->UPB_ONLYBITS(data) = (uintptr_t)data | bits; +} + +UPB_INLINE size_t +UPB_PRIVATE(_upb_Array_ElemSizeLg2)(const struct upb_Array* array) { + const size_t bits = array->UPB_ONLYBITS(data) & _UPB_ARRAY_MASK_LG2; + const size_t lg2 = bits + (bits != 0); + return lg2; +} + +UPB_API_INLINE const void* upb_Array_DataPtr(const struct upb_Array* array) { + UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); // Check assertions. + return (void*)(array->UPB_ONLYBITS(data) & ~(uintptr_t)_UPB_ARRAY_MASK_ALL); +} + +UPB_API_INLINE void* upb_Array_MutableDataPtr(struct upb_Array* array) { + return (void*)upb_Array_DataPtr(array); +} + +UPB_INLINE struct upb_Array* UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)( + upb_Arena* arena, size_t init_capacity, int elem_size_lg2, + bool allow_slow) { + UPB_ASSERT(elem_size_lg2 != 1); + UPB_ASSERT(elem_size_lg2 <= 4); + const size_t array_size = + UPB_ALIGN_UP(sizeof(struct upb_Array), UPB_MALLOC_ALIGN); + const size_t bytes = array_size + (init_capacity << elem_size_lg2); + size_t span = UPB_PRIVATE(_upb_Arena_AllocSpan)(bytes); + if (!allow_slow && UPB_PRIVATE(_upb_ArenaHas)(arena) < span) return NULL; + struct upb_Array* array = (struct upb_Array*)upb_Arena_Malloc(arena, bytes); + if (!array) return NULL; + UPB_PRIVATE(_upb_Array_SetTaggedPtr) + (array, UPB_PTR_AT(array, array_size, void), (size_t)elem_size_lg2); + array->UPB_ONLYBITS(size) = 0; + array->UPB_PRIVATE(capacity) = init_capacity; + return array; +} + +UPB_INLINE struct upb_Array* UPB_PRIVATE(_upb_Array_New)(upb_Arena* arena, + size_t init_capacity, + int elem_size_lg2) { + return UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)(arena, init_capacity, + elem_size_lg2, true); +} + +UPB_INLINE struct upb_Array* UPB_PRIVATE(_upb_Array_TryFastNew)( + upb_Arena* arena, size_t init_capacity, int elem_size_lg2) { + return UPB_PRIVATE(_upb_Array_NewMaybeAllowSlow)(arena, init_capacity, + elem_size_lg2, false); +} + +// Resizes the capacity of the array to be at least min_size. +bool UPB_PRIVATE(_upb_Array_Realloc)(struct upb_Array* array, size_t min_size, + upb_Arena* arena); + +UPB_FORCEINLINE +bool UPB_PRIVATE(_upb_Array_TryFastRealloc)(struct upb_Array* array, + size_t capacity, int elem_size_lg2, + upb_Arena* arena) { + size_t old_bytes = array->UPB_PRIVATE(capacity) << elem_size_lg2; + size_t new_bytes = capacity << elem_size_lg2; + UPB_ASSUME(new_bytes > old_bytes); + if (!upb_Arena_TryExtend(arena, array, old_bytes, new_bytes)) return false; + array->UPB_PRIVATE(capacity) = capacity; + return true; +} + +UPB_API_INLINE bool upb_Array_Reserve(struct upb_Array* array, size_t size, + upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(array)); + if (array->UPB_PRIVATE(capacity) < size) + return UPB_PRIVATE(_upb_Array_Realloc)(array, size, arena); + return true; +} + +// Resize without initializing new elements. +UPB_INLINE bool UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + struct upb_Array* array, size_t size, upb_Arena* arena) { + UPB_ASSERT(!upb_Array_IsFrozen(array)); + UPB_ASSERT(size <= array->UPB_ONLYBITS(size) || + arena); // Allow NULL arena when shrinking. + if (!upb_Array_Reserve(array, size, arena)) return false; + array->UPB_ONLYBITS(size) = size; + return true; +} + +// This function is intended for situations where elem_size is compile-time +// constant or a known expression of the form (1 << lg2), so that the expression +// i*elem_size does not result in an actual multiplication. +UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(struct upb_Array* array, size_t i, + const void* data, + size_t elem_size) { + UPB_ASSERT(!upb_Array_IsFrozen(array)); + UPB_ASSERT(i < array->UPB_ONLYBITS(size)); + UPB_ASSERT(elem_size == 1U << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array)); + char* arr_data = (char*)upb_Array_MutableDataPtr(array); + memcpy(arr_data + (i * elem_size), data, elem_size); +} + +UPB_API_INLINE size_t upb_Array_Size(const struct upb_Array* arr) { + return arr->UPB_ONLYBITS(size); +} + +UPB_API_INLINE size_t upb_Array_Capacity(const struct upb_Array* arr) { + return arr->UPB_PRIVATE(capacity); +} + +// LINT.ThenChange(GoogleInternalName0) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#undef _UPB_ARRAY_MASK_IMM +#undef _UPB_ARRAY_MASK_LG2 +#undef _UPB_ARRAY_MASK_ALL + + +#endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_TYPES_H_ +#define UPB_MESSAGE_INTERNAL_TYPES_H_ + +#include <stdint.h> + +// Must be last. + +#define UPB_OPAQUE(x) x##_opaque + +struct upb_Message { + union { + uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen + double d; // Forces same size for 32-bit/64-bit builds + }; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(_upb_Message_ShallowFreeze)( + struct upb_Message* msg) { + msg->UPB_OPAQUE(internal) |= 1ULL; +} + +UPB_API_INLINE bool upb_Message_IsFrozen(const struct upb_Message* msg) { + return (msg->UPB_OPAQUE(internal) & 1ULL) != 0; +} + +UPB_INLINE struct upb_Message_Internal* UPB_PRIVATE(_upb_Message_GetInternal)( + const struct upb_Message* msg) { + const uintptr_t tmp = msg->UPB_OPAQUE(internal) & ~1ULL; + return (struct upb_Message_Internal*)tmp; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetInternal)( + struct upb_Message* msg, struct upb_Message_Internal* internal) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + msg->UPB_OPAQUE(internal) = (uintptr_t)internal; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#undef UPB_OPAQUE + + +#endif /* UPB_MESSAGE_INTERNAL_TYPES_H_ */ + +// Users should include array.h or map.h instead. +// IWYU pragma: private, include "upb/message/array.h" + +#ifndef UPB_MESSAGE_VALUE_H_ +#define UPB_MESSAGE_VALUE_H_ + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef union { + bool bool_val; + float float_val; + double double_val; + int32_t int32_val; + int64_t int64_val; + uint32_t uint32_val; + uint64_t uint64_val; + const struct upb_Array* array_val; + const struct upb_Map* map_val; + const struct upb_Message* msg_val; + upb_StringView str_val; + + // For an extension field, we are essentially treating ext->data (a + // upb_MessageValue) as if it were a message with one field that lives at + // offset 0. This works because upb_MessageValue is precisely one value that + // can hold any type of data. Recall that an extension can be of any type + // (scalar, repeated, or message). For a message extension, that will be a + // single upb_Message* at offset 0 of the upb_MessageValue. + struct upb_Message UPB_PRIVATE(ext_msg_val); +} upb_MessageValue; + +UPB_API_INLINE upb_MessageValue upb_MessageValue_Zero(void) { + upb_MessageValue zero; + memset(&zero, 0, sizeof(zero)); + return zero; +} + +typedef union { + struct upb_Array* array; + struct upb_Map* map; + struct upb_Message* msg; +} upb_MutableMessageValue; + +UPB_API_INLINE upb_MutableMessageValue upb_MutableMessageValue_Zero(void) { + upb_MutableMessageValue zero; + memset(&zero, 0, sizeof(zero)); + return zero; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_VALUE_H_ */ + +#ifndef UPB_MINI_TABLE_MESSAGE_H_ +#define UPB_MINI_TABLE_MESSAGE_H_ + +#include <stdint.h> + + +#ifndef UPB_MINI_TABLE_ENUM_H_ +#define UPB_MINI_TABLE_ENUM_H_ + +#include <stdint.h> + + +#ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ +#define UPB_MINI_TABLE_INTERNAL_ENUM_H_ + +#include <stdint.h> + +// Must be last. + +struct upb_MiniTableEnum { + uint32_t UPB_PRIVATE(mask_limit); // Highest that can be tested with mask. + uint32_t UPB_PRIVATE(value_count); // Number of values after the bitfield. + uint32_t UPB_PRIVATE(data)[]; // Bitmask + enumerated values follow. +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE bool upb_MiniTableEnum_CheckValue( + const struct upb_MiniTableEnum* e, uint32_t val) { + if (UPB_LIKELY(val < 64)) { + const uint64_t mask = + e->UPB_PRIVATE(data)[0] | ((uint64_t)e->UPB_PRIVATE(data)[1] << 32); + const uint64_t bit = 1ULL << val; + return (mask & bit) != 0; + } + if (UPB_LIKELY(val < e->UPB_PRIVATE(mask_limit))) { + const uint32_t mask = e->UPB_PRIVATE(data)[val / 32]; + const uint32_t bit = 1U << (val % 32); + return (mask & bit) != 0; + } + + // OPT: binary search long lists? + const uint32_t* start = + &e->UPB_PRIVATE(data)[e->UPB_PRIVATE(mask_limit) / 32]; + const uint32_t* limit = &e->UPB_PRIVATE( + data)[e->UPB_PRIVATE(mask_limit) / 32 + e->UPB_PRIVATE(value_count)]; + for (const uint32_t* p = start; p < limit; p++) { + if (*p == val) return true; + } + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_ENUM_H_ */ + +// Must be last + +typedef struct upb_MiniTableEnum upb_MiniTableEnum; + +#ifdef __cplusplus +extern "C" { +#endif + +// Validates enum value against range defined by enum mini table. +UPB_API_INLINE bool upb_MiniTableEnum_CheckValue(const upb_MiniTableEnum* e, + uint32_t val); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_ENUM_H_ */ + +#ifndef UPB_MINI_TABLE_FIELD_H_ +#define UPB_MINI_TABLE_FIELD_H_ + +#include <stdint.h> + + +#ifndef UPB_MINI_TABLE_INTERNAL_FIELD_H_ +#define UPB_MINI_TABLE_INTERNAL_FIELD_H_ + +#include <stddef.h> +#include <stdint.h> + + +#ifndef UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ +#define UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Return the log2 of the storage size in bytes for a upb_CType +UPB_INLINE int UPB_PRIVATE(_upb_CType_SizeLg2)(upb_CType c_type) { + static const int8_t size[] = { + 0, // kUpb_CType_Bool + 2, // kUpb_CType_Float + 2, // kUpb_CType_Int32 + 2, // kUpb_CType_UInt32 + 2, // kUpb_CType_Enum + UPB_SIZE(2, 3), // kUpb_CType_Message + 3, // kUpb_CType_Double + 3, // kUpb_CType_Int64 + 3, // kUpb_CType_UInt64 + UPB_SIZE(3, 4), // kUpb_CType_String + UPB_SIZE(3, 4), // kUpb_CType_Bytes + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[c_type - 1]; +} + +// Return the log2 of the storage size in bytes for a upb_FieldType +UPB_INLINE size_t +UPB_PRIVATE(_upb_FieldType_SizeLg2)(upb_FieldType field_type) { + static const int8_t size[] = { + 3, // kUpb_FieldType_Double + 2, // kUpb_FieldType_Float + 3, // kUpb_FieldType_Int64 + 3, // kUpb_FieldType_UInt64 + 2, // kUpb_FieldType_Int32 + 3, // kUpb_FieldType_Fixed64 + 2, // kUpb_FieldType_Fixed32 + 0, // kUpb_FieldType_Bool + UPB_SIZE(3, 4), // kUpb_FieldType_String + UPB_SIZE(2, 3), // kUpb_FieldType_Group + UPB_SIZE(2, 3), // kUpb_FieldType_Message + UPB_SIZE(3, 4), // kUpb_FieldType_Bytes + 2, // kUpb_FieldType_UInt32 + 2, // kUpb_FieldType_Enum + 2, // kUpb_FieldType_SFixed32 + 3, // kUpb_FieldType_SFixed64 + 2, // kUpb_FieldType_SInt32 + 3, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[field_type - 1]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ */ + +// Must be last. + +// LINT.IfChange(struct_definition) +struct upb_MiniTableField { + uint32_t UPB_ONLYBITS(number); + uint16_t UPB_ONLYBITS(offset); + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + + // Offset from this upb_MiniTableField to the upb_MiniTableSubInternal + // for this field, in uint32_t units (so bytes/4). + // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM + uint16_t UPB_PRIVATE(submsg_ofs); + + uint8_t UPB_PRIVATE(descriptortype); + + // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift) + uint8_t UPB_ONLYBITS(mode); +}; + +#define kUpb_NoSub ((uint16_t)-1) +#define kUpb_SubmsgOffsetBytes 4 + +typedef enum { + kUpb_FieldMode_Map = 0, + kUpb_FieldMode_Array = 1, + kUpb_FieldMode_Scalar = 2, +} upb_FieldMode; + +// Mask to isolate the upb_FieldMode from field.mode. +#define kUpb_FieldMode_Mask 3 + +// Extra flags on the mode field. +typedef enum { + kUpb_LabelFlags_IsPacked = 4, + kUpb_LabelFlags_IsExtension = 8, + // Indicates that this descriptor type is an "alternate type": + // - for Int32, this indicates that the actual type is Enum (but was + // rewritten to Int32 because it is an open enum that requires no check). + // - for Bytes, this indicates that the actual type is String (but does + // not require any UTF-8 check). + kUpb_LabelFlags_IsAlternate = 16, +} upb_LabelFlags; + +// Note: we sort by this number when calculating layout order. +typedef enum { + kUpb_FieldRep_1Byte = 0, + kUpb_FieldRep_4Byte = 1, + kUpb_FieldRep_StringView = 2, + kUpb_FieldRep_8Byte = 3, + + kUpb_FieldRep_NativePointer = + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte), + kUpb_FieldRep_Max = kUpb_FieldRep_8Byte, +} upb_FieldRep; + +#define kUpb_FieldRep_Shift 6 + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE upb_FieldMode +UPB_PRIVATE(_upb_MiniTableField_Mode)(const struct upb_MiniTableField* f) { + return (upb_FieldMode)(f->UPB_ONLYBITS(mode) & kUpb_FieldMode_Mask); +} + +UPB_INLINE upb_FieldRep +UPB_PRIVATE(_upb_MiniTableField_GetRep)(const struct upb_MiniTableField* f) { + return (upb_FieldRep)(f->UPB_ONLYBITS(mode) >> kUpb_FieldRep_Shift); +} + +UPB_API_INLINE bool upb_MiniTableField_IsArray( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Array; +} + +UPB_API_INLINE bool upb_MiniTableField_IsMap( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Map; +} + +UPB_API_INLINE bool upb_MiniTableField_IsScalar( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Scalar; +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsAlternate)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) != 0; +} + +UPB_API_INLINE bool upb_MiniTableField_IsExtension( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsExtension) != 0; +} + +UPB_API_INLINE bool upb_MiniTableField_IsPacked( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsPacked) != 0; +} + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const struct upb_MiniTableField* f) { + const upb_FieldType type = (upb_FieldType)f->UPB_PRIVATE(descriptortype); + if (UPB_PRIVATE(_upb_MiniTableField_IsAlternate)(f)) { + if (type == kUpb_FieldType_Int32) return kUpb_FieldType_Enum; + if (type == kUpb_FieldType_Bytes) return kUpb_FieldType_String; + UPB_ASSERT(false); + } + return type; +} + +UPB_API_INLINE +upb_CType upb_MiniTableField_CType(const struct upb_MiniTableField* f) { + return upb_FieldType_CType(upb_MiniTableField_Type(f)); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_HasHasbit)( + const struct upb_MiniTableField* f) { + return f->presence > 0; +} + +UPB_INLINE char UPB_PRIVATE(_upb_MiniTableField_HasbitMask)( + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)); + const uint16_t index = (uint16_t)f->presence; + return (char)(1 << (index % 8)); +} + +UPB_INLINE uint16_t UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)( + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)); + const uint16_t index = (uint16_t)f->presence; + return index / 8; +} + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +} + +UPB_API_INLINE bool upb_MiniTableField_IsInOneof( + const struct upb_MiniTableField* f) { + return f->presence < 0; +} + +UPB_API_INLINE bool upb_MiniTableField_IsSubMessage( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || + f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +} + +UPB_API_INLINE bool upb_MiniTableField_HasPresence( + const struct upb_MiniTableField* f) { + if (upb_MiniTableField_IsExtension(f)) { + return upb_MiniTableField_IsScalar(f); + } else { + return f->presence != 0; + } +} + +UPB_API_INLINE uint32_t +upb_MiniTableField_Number(const struct upb_MiniTableField* f) { + return f->UPB_ONLYBITS(number); +} + +UPB_INLINE uint16_t +UPB_PRIVATE(_upb_MiniTableField_Offset)(const struct upb_MiniTableField* f) { + return f->UPB_ONLYBITS(offset); +} + +UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_OneofOffset)( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_IsInOneof(f)); + return (size_t)(~(ptrdiff_t)f->presence); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsArray(f)); + UPB_ASSUME(f->presence == 0); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsMap(f)); + UPB_ASSUME(f->presence == 0); +} + +UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)( + const struct upb_MiniTableField* f) { + const upb_FieldType field_type = upb_MiniTableField_Type(f); + return UPB_PRIVATE(_upb_FieldType_SizeLg2)(field_type); +} + +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table_field.ts) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ + +// Must be last. + +typedef struct upb_MiniTableField upb_MiniTableField; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_HasPresence(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsArray(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsExtension(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsInOneof(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsMap(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsPacked(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsScalar(const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_MiniTableField_IsSubMessage( + const upb_MiniTableField* f); + +UPB_API_INLINE uint32_t upb_MiniTableField_Number(const upb_MiniTableField* f); + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const upb_MiniTableField* f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_FIELD_H_ */ + +#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ + +#include <stddef.h> +#include <stdint.h> + + +#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ +#define UPB_MINI_TABLE_INTERNAL_SUB_H_ + +// Must be last. + +union upb_MiniTableSub { + const struct upb_MiniTable* UPB_PRIVATE(submsg); + const struct upb_MiniTableEnum* UPB_PRIVATE(subenum); +}; + +typedef union upb_MiniTableSub upb_MiniTableSubInternal; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE union upb_MiniTableSub upb_MiniTableSub_FromEnum( + const struct upb_MiniTableEnum* subenum) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(subenum) = subenum; + return out; +} + +UPB_API_INLINE union upb_MiniTableSub upb_MiniTableSub_FromMessage( + const struct upb_MiniTable* submsg) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(submsg) = submsg; + return out; +} + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(subenum); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(submsg); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ + +// Must be last. + +struct upb_Decoder; +struct upb_Message; + +typedef UPB_PRESERVE_NONE const char* _upb_FieldParser( + struct upb_Decoder* d, const char* ptr, struct upb_Message* msg, + intptr_t table, uint64_t hasbits, uint64_t data); + +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +enum { + kUpb_Message_Align = 8, +}; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. + +// LINT.IfChange(minitable_struct_definition) +struct upb_MiniTable { + const struct upb_MiniTableField* UPB_ONLYBITS(fields); + + // Must be aligned to kUpb_Message_Align. Doesn't include internal members + // like unknown fields, extension dict, pointer to msglayout, etc. + uint16_t UPB_PRIVATE(size); + + uint16_t UPB_ONLYBITS(field_count); + + uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1 + uint8_t UPB_PRIVATE(dense_below); + uint8_t UPB_PRIVATE(table_mask); + uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits. + +#ifdef UPB_TRACING_ENABLED + const char* UPB_PRIVATE(full_name); +#endif + +#if UPB_FASTTABLE || !defined(__cplusplus) + // Flexible array member is not supported in C++, but it is an extension in + // every compiler that supports UPB_FASTTABLE. + _upb_FastTable_Entry UPB_PRIVATE(fasttable)[]; +#endif +}; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table.ts) + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(upb_MiniTable_CheckInvariants)( + const struct upb_MiniTable* mt) { + UPB_STATIC_ASSERT(UPB_MALLOC_ALIGN >= kUpb_Message_Align, "Under aligned"); + UPB_STATIC_ASSERT(kUpb_Message_Align >= UPB_ALIGN_OF(void*), "Under aligned"); + UPB_ASSERT(mt->UPB_PRIVATE(size) % kUpb_Message_Align == 0); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTable_StrongReference)(const struct upb_MiniTable* mt) { +#if defined(__GNUC__) + __asm__("" : : "r"(mt)); +#else + const struct upb_MiniTable* volatile unused = mt; + (void)&unused; // Use address to avoid an extra load of "unused". +#endif + return mt; +} + +UPB_API_INLINE int upb_MiniTable_FieldCount(const struct upb_MiniTable* m) { + return m->UPB_ONLYBITS(field_count); +} + +UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const struct upb_MiniTable* m) { + return m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet; +} + +UPB_API_INLINE +const struct upb_MiniTableField* upb_MiniTable_FindFieldByNumber( + const struct upb_MiniTable* m, uint32_t number) { + const uint32_t i = number - 1; // 0 wraps to UINT32_MAX + + // Ideal case: index into dense fields + if (i < m->UPB_PRIVATE(dense_below)) { + UPB_ASSERT(m->UPB_ONLYBITS(fields)[i].UPB_ONLYBITS(number) == number); + return &m->UPB_ONLYBITS(fields)[i]; + } + + // Early exit if the field number is out of range. + int32_t hi = m->UPB_ONLYBITS(field_count) - 1; + if (hi < 0 || number > m->UPB_ONLYBITS(fields)[hi].UPB_ONLYBITS(number)) { + return NULL; + } + + // Slow case: binary search + uint32_t lo = m->UPB_PRIVATE(dense_below); + const struct upb_MiniTableField* base = m->UPB_ONLYBITS(fields); + while (hi >= (int32_t)lo) { + uint32_t mid = ((uint32_t)hi + lo) / 2; + uint32_t num = base[mid].UPB_ONLYBITS(number); + // These comparison operations allow, on ARM machines, to fuse all these + // branches into one comparison followed by two CSELs to set the lo/hi + // values, followed by a BNE to continue or terminate the loop. Since binary + // search branches are generally unpredictable (50/50 in each direction), + // this is a good deal. We use signed for the high, as this decrement may + // underflow if mid is 0. + int32_t hi_mid = (int32_t)mid - 1; + uint32_t lo_mid = mid + 1; + if (num == number) { + return &base[mid]; + } + if (UPB_UNPREDICTABLE(num < number)) { + lo = lo_mid; + } else { + hi = hi_mid; + } + } + + return NULL; +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_GetFieldByIndex( + const struct upb_MiniTable* m, uint32_t i) { + UPB_ASSERT(i < m->UPB_ONLYBITS(field_count)); + return &m->UPB_ONLYBITS(fields)[i]; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Message); + upb_MiniTableSubInternal* sub = + UPB_PTR_AT(f, f->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + return sub->UPB_PRIVATE(submsg); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_SubMessage( + const struct upb_MiniTableField* f) { + if (upb_MiniTableField_CType(f) != kUpb_CType_Message) { + return NULL; + } + return upb_MiniTable_GetSubMessageTable(f); +} + +UPB_API_INLINE bool upb_MiniTable_FieldIsLinked( + const struct upb_MiniTableField* f) { + return upb_MiniTable_GetSubMessageTable(f) != NULL; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_MapEntrySubMessage( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTable_FieldIsLinked(f)); // Map entries must be linked. + UPB_ASSERT(upb_MiniTableField_IsMap(f)); // Function precondition. + return upb_MiniTable_GetSubMessageTable(f); +} + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const struct upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum); + upb_MiniTableSubInternal* sub = + UPB_PTR_AT(f, f->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes, + upb_MiniTableSubInternal); + return sub->UPB_PRIVATE(subenum); +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_MapKey( + const struct upb_MiniTable* m) { + UPB_ASSERT(upb_MiniTable_FieldCount(m) == 2); + const struct upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, 0); + UPB_ASSERT(upb_MiniTableField_Number(f) == 1); + return f; +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTable_MapValue( + const struct upb_MiniTable* m) { + UPB_ASSERT(upb_MiniTable_FieldCount(m) == 2); + const struct upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, 1); + UPB_ASSERT(upb_MiniTableField_Number(f) == 2); + return f; +} + +// Computes a bitmask in which the |m->required_count| lowest bits are set. +// +// Sample output: +// RequiredMask(1) => 0b1 (0x1) +// RequiredMask(5) => 0b11111 (0x1f) +UPB_INLINE uint64_t +UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) { + int n = m->UPB_PRIVATE(required_count); + UPB_ASSERT(0 < n && n <= 64); + return (1ULL << n) - 1; +} + +#ifdef UPB_TRACING_ENABLED +UPB_INLINE const char* upb_MiniTable_FullName( + const struct upb_MiniTable* mini_table) { + return mini_table->UPB_PRIVATE(full_name); +} +// Initializes tracing proto name from language runtimes that construct +// mini tables dynamically at runtime. The runtime is responsible for passing +// controlling lifetime of name such as storing in same arena as mini_table. +UPB_INLINE void upb_MiniTable_SetFullName(struct upb_MiniTable* mini_table, + const char* full_name) { + mini_table->UPB_PRIVATE(full_name) = full_name; +} +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + +// Must be last. + +typedef struct upb_MiniTable upb_MiniTable; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( + const upb_MiniTable* m, uint32_t number); + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( + const upb_MiniTable* m, uint32_t index); + +UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m); + +UPB_API_INLINE bool upb_MiniTable_IsMessageSet(const upb_MiniTable* m); + +// DEPRECATED: use upb_MiniTable_SubMessage() instead +// Returns the MiniTable for a message field, NULL if the field is unlinked. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const upb_MiniTableField* f); + +// Returns the MiniTable for a message field if it is a submessage and the field +// is linked, otherwise returns NULL. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_SubMessage( + const upb_MiniTableField* f); + +// Returns the MiniTable for a map field. The given field must refer to a map. +UPB_API_INLINE const upb_MiniTable* upb_MiniTable_MapEntrySubMessage( + const upb_MiniTableField* f); + +// Returns the MiniTableEnum for a message field, NULL if the field is unlinked. +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const upb_MiniTableField* f); + +// Returns the MiniTableField for the key of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapKey( + const upb_MiniTable* m); + +// Returns the MiniTableField for the value of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapValue( + const upb_MiniTable* m); + +// Returns true if this MiniTable field is linked to a MiniTable for the +// sub-message. +UPB_API_INLINE bool upb_MiniTable_FieldIsLinked(const upb_MiniTableField* f); + +// If this field is in a oneof, returns the first field in the oneof. +// +// Otherwise returns NULL. +// +// Usage: +// const upb_MiniTableField* field = upb_MiniTable_GetOneof(m, f); +// do { +// .. +// } while (upb_MiniTable_NextOneofField(m, &field); +// +const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Iterates to the next field in the oneof. If this is the last field in the +// oneof, returns false. The ordering of fields in the oneof is not +// guaranteed. +// REQUIRES: |f| is the field initialized by upb_MiniTable_GetOneof and updated +// by prior upb_MiniTable_NextOneofField calls. +bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, + const upb_MiniTableField** f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +// Temporary overloads for functions whose signature has recently changed. +UPB_DEPRECATE_AND_INLINE() +inline const upb_MiniTable* upb_MiniTable_SubMessage( + const upb_MiniTable* m, const upb_MiniTableField* f) { + return upb_MiniTable_SubMessage(f); +} + +UPB_DEPRECATE_AND_INLINE() +inline const upb_MiniTable* upb_MiniTable_GetSubMessageTable( + const upb_MiniTable* m, const upb_MiniTableField* f) { + return upb_MiniTable_GetSubMessageTable(f); +} + +UPB_DEPRECATE_AND_INLINE() +inline const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( + const upb_MiniTable* m, const upb_MiniTableField* f) { + return upb_MiniTable_GetSubEnumTable(f); +} + +UPB_DEPRECATE_AND_INLINE() +inline bool upb_MiniTable_FieldIsLinked(const upb_MiniTable* m, + const upb_MiniTableField* f) { + return upb_MiniTable_FieldIsLinked(f); +} +#endif + + +#endif /* UPB_MINI_TABLE_MESSAGE_H_ */ + +// Must be last. + +typedef struct upb_Array upb_Array; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates a new array on the given arena that holds elements of this type. +UPB_API upb_Array* upb_Array_New(upb_Arena* a, upb_CType type); + +// Returns the number of elements in the array. +UPB_API_INLINE size_t upb_Array_Size(const upb_Array* arr); + +// Returns the number of elements in the array. +UPB_API_INLINE size_t upb_Array_Capacity(const upb_Array* arr); + +// Returns the given element, which must be within the array's current size. +UPB_API upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i); + +// Returns a non-null mutating pointer to the given element. `arr` must be an +// array of a message type, and `i` must be within the array's current size. +UPB_API struct upb_Message* upb_Array_GetMutable(upb_Array* arr, size_t i); + +// Sets the given element, which must be within the array's current size. +UPB_API void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val); + +// Appends an element to the array. Returns false on allocation failure. +UPB_API bool upb_Array_Append(upb_Array* array, upb_MessageValue val, + upb_Arena* arena); + +// Copies elements from |src| to |dst|, resizing |dst| to match |src| size. +// Returns false on allocation failure. +UPB_API bool upb_Array_Copy(upb_Array* dst, const upb_Array* src, + upb_Arena* arena); + +// Appends all elements from |src| to the end of |dst|. +// Returns false on allocation failure. +UPB_API bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src, + upb_Arena* arena); + +// Moves elements within the array using memmove(). +// Like memmove(), the source and destination elements may be overlapping. +UPB_API void upb_Array_Move(upb_Array* array, size_t dst_idx, size_t src_idx, + size_t count); + +// Inserts one or more empty elements into the array. +// Existing elements are shifted right. +// The new elements have undefined state and must be set with `upb_Array_Set()`. +// REQUIRES: `i <= upb_Array_Size(arr)` +UPB_API bool upb_Array_Insert(upb_Array* array, size_t i, size_t count, + upb_Arena* arena); + +// Deletes one or more elements from the array. +// Existing elements are shifted left. +// REQUIRES: `i + count <= upb_Array_Size(arr)` +UPB_API void upb_Array_Delete(upb_Array* array, size_t i, size_t count); + +// Reserves |size| elements of storage for the array. +UPB_API_INLINE bool upb_Array_Reserve(struct upb_Array* array, size_t size, + upb_Arena* arena); + +// Changes the size of a vector. New elements are initialized to NULL/0. +// Returns false on allocation failure. +UPB_API bool upb_Array_Resize(upb_Array* array, size_t size, upb_Arena* arena); + +// Returns pointer to array data. +UPB_API_INLINE const void* upb_Array_DataPtr(const upb_Array* arr); + +// Returns mutable pointer to array data. +UPB_API_INLINE void* upb_Array_MutableDataPtr(upb_Array* arr); + +// Mark an array and all of its descendents as frozen/immutable. +// If the array elements are messages then |m| must point to the minitable for +// those messages. Otherwise |m| must be NULL. +UPB_API void upb_Array_Freeze(upb_Array* arr, const upb_MiniTable* m); + +// Returns whether an array has been frozen. +UPB_API_INLINE bool upb_Array_IsFrozen(const upb_Array* arr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_ARRAY_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_ACCESSORS_H_ +#define UPB_MESSAGE_INTERNAL_ACCESSORS_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +#ifndef UPB_BASE_INTERNAL_ENDIAN_H_ +#define UPB_BASE_INTERNAL_ENDIAN_H_ + +#include <stdint.h> + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE bool upb_IsLittleEndian(void) { + const int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t upb_BigEndian32(uint32_t val) { + if (upb_IsLittleEndian()) return val; + + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} + +UPB_INLINE uint64_t upb_BigEndian64(uint64_t val) { + if (upb_IsLittleEndian()) return val; + + const uint64_t hi = ((uint64_t)upb_BigEndian32((uint32_t)val)) << 32; + const uint64_t lo = upb_BigEndian32((uint32_t)(val >> 32)); + return hi | lo; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_INTERNAL_ENDIAN_H_ */ + +#ifndef UPB_MESSAGE_INTERNAL_EXTENSION_H_ +#define UPB_MESSAGE_INTERNAL_EXTENSION_H_ + +#include <stddef.h> + + +#ifndef UPB_MESSAGE_INTERNAL_MAP_H_ +#define UPB_MESSAGE_INTERNAL_MAP_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +/* + * upb_table + * + * This header is INTERNAL-ONLY! Its interfaces are not public or stable! + * This file defines very fast int->upb_value (inttable) and string->upb_value + * (strtable) hash tables. + * + * The table uses chained scatter with Brent's variation (inspired by the Lua + * implementation of hash tables). The hash function for strings is Austin + * Appleby's "MurmurHash." + * + * The inttable uses uintptr_t as its key, which guarantees it can be used to + * store pointers or integers of at least 32 bits (upb isn't really useful on + * systems where sizeof(void*) < 4). + * + * The table must be homogeneous (all values of the same type). In debug + * mode, we check this on insert and lookup. + */ + +#ifndef UPB_HASH_COMMON_H_ +#define UPB_HASH_COMMON_H_ + +#include <stdint.h> +#include <string.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* upb_value ******************************************************************/ + +typedef struct { + uint64_t val; +} upb_value; + +/* For each value ctype, define the following set of functions: + * + * // Get/set an int32 from a upb_value. + * int32_t upb_value_getint32(upb_value val); + * void upb_value_setint32(upb_value *val, int32_t cval); + * + * // Construct a new upb_value from an int32. + * upb_value upb_value_int32(int32_t val); */ +#define FUNCS(name, membername, type_t, converter) \ + UPB_INLINE void upb_value_set##name(upb_value* val, type_t cval) { \ + val->val = (uint64_t)cval; \ + } \ + UPB_INLINE upb_value upb_value_##name(type_t val) { \ + upb_value ret; \ + upb_value_set##name(&ret, val); \ + return ret; \ + } \ + UPB_INLINE type_t upb_value_get##name(upb_value val) { \ + return (type_t)(converter)val.val; \ + } + +FUNCS(int32, int32, int32_t, int32_t) +FUNCS(int64, int64, int64_t, int64_t) +FUNCS(uint32, uint32, uint32_t, uint32_t) +FUNCS(uint64, uint64, uint64_t, uint64_t) +FUNCS(bool, _bool, bool, bool) +FUNCS(cstr, cstr, char*, uintptr_t) +FUNCS(uintptr, uptr, uintptr_t, uintptr_t) +FUNCS(ptr, ptr, void*, uintptr_t) +FUNCS(constptr, constptr, const void*, uintptr_t) + +#undef FUNCS + +UPB_INLINE void upb_value_setfloat(upb_value* val, float cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} + +UPB_INLINE void upb_value_setdouble(upb_value* val, double cval) { + memcpy(&val->val, &cval, sizeof(cval)); +} + +UPB_INLINE upb_value upb_value_float(float cval) { + upb_value ret; + upb_value_setfloat(&ret, cval); + return ret; +} + +UPB_INLINE upb_value upb_value_double(double cval) { + upb_value ret; + upb_value_setdouble(&ret, cval); + return ret; +} + +/* upb_key *****************************************************************/ + +// A uint32 size followed by that number of bytes stored contiguously. +typedef struct { + uint32_t size; + const char data[]; +} upb_SizePrefixString; + +/* Either: + * 1. an actual integer key + * 2. a SizePrefixString*, owned by us. + * + * ...depending on whether this is a string table or an int table. */ +typedef union { + uintptr_t num; + const upb_SizePrefixString* str; +} upb_key; + +UPB_INLINE upb_StringView upb_key_strview(upb_key key) { + return upb_StringView_FromDataAndSize(key.str->data, key.str->size); +} + +/* upb_table ******************************************************************/ + +typedef struct _upb_tabent { + upb_value val; + upb_key key; + + /* Internal chaining. This is const so we can create static initializers for + * tables. We cast away const sometimes, but *only* when the containing + * upb_table is known to be non-const. This requires a bit of care, but + * the subtlety is confined to table.c. */ + const struct _upb_tabent* next; +} upb_tabent; + +typedef struct { + upb_tabent* entries; + /* Number of entries in the hash part. */ + uint32_t count; + + /* Mask to turn hash value -> bucket. The map's allocated size is mask + 1.*/ + uint32_t mask; +} upb_table; + +UPB_INLINE size_t upb_table_size(const upb_table* t) { return t->mask + 1; } + +// Internal-only functions, in .h file only out of necessity. + +UPB_INLINE upb_key upb_key_empty(void) { + upb_key ret; + memset(&ret, 0, sizeof(upb_key)); + return ret; +} + +UPB_INLINE bool upb_tabent_isempty(const upb_tabent* e) { + upb_key key = e->key; + UPB_STATIC_ASSERT(sizeof(key.num) == sizeof(key.str), "Sizes don't match"); + uintptr_t val; + memcpy(&val, &key, sizeof(val)); + // Note: for upb_inttables a tab_key is a true integer key value, but the + // inttable maintains the invariant that 0 value is always stored in the + // compact table and never as a upb_tabent* so we can always use the 0 + // key value to identify an empty tabent. + return val == 0; +} + +uint32_t _upb_Hash(const void* p, size_t n, uint64_t seed); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_COMMON_H_ */ + +#ifndef UPB_HASH_INT_TABLE_H_ +#define UPB_HASH_INT_TABLE_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +typedef struct { + upb_table t; // For entries that don't fit in the array part. + // Array part of the table. + // Pointers on this table are const so we can create static initializers for + // tables. We cast away const sometimes, but *only* when the containing + // upb_table is known to be non-const. This requires a bit of care, but + // the subtlety is confined to table.c. + const upb_value* array; + // Track presence in the array part. Each bit at index (key % 8) at the + // presence_mask[key/8] indicates if the element is present in the array part. + const uint8_t* presence_mask; + uint32_t array_size; // Array part size. + uint32_t array_count; // Array part number of elements. +} upb_inttable; + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize a table. If memory allocation failed, false is returned and +// the table is uninitialized. +bool upb_inttable_init(upb_inttable* table, upb_Arena* a); + +// Returns the number of values in the table. +size_t upb_inttable_count(const upb_inttable* t); + +// Inserts the given key into the hashtable with the given value. +// The key must not already exist in the hash table. +// The value must not be UINTPTR_MAX. +// +// If a table resize was required but memory allocation failed, false is +// returned and the table is unchanged. +bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val, + upb_Arena* a); + +// Looks up key in this table, returning "true" if the key was found. +// If v is non-NULL, copies the value for this key into *v. +bool upb_inttable_lookup(const upb_inttable* t, uintptr_t key, upb_value* v); + +// Removes an item from the table. Returns true if the remove was successful, +// and stores the removed item in *val if non-NULL. +bool upb_inttable_remove(upb_inttable* t, uintptr_t key, upb_value* val); + +// Updates an existing entry in an inttable. +// If the entry does not exist, returns false and does nothing. +// Unlike insert/remove, this does not invalidate iterators. +bool upb_inttable_replace(upb_inttable* t, uintptr_t key, upb_value val); + +// Optimizes the table for the current set of entries, for both memory use and +// lookup time. Client should call this after all entries have been inserted; +// inserting more entries is legal, but will likely require a table resize. +// Returns false if reallocation fails. +bool upb_inttable_compact(upb_inttable* t, upb_Arena* a); + +// Clears the table. +void upb_inttable_clear(upb_inttable* t); + +// Iteration over inttable: +// +// intptr_t iter = UPB_INTTABLE_BEGIN; +// uintptr_t key; +// upb_value val; +// while (upb_inttable_next(t, &key, &val, &iter)) { +// // ... +// } + +#define UPB_INTTABLE_BEGIN -1 + +bool upb_inttable_next(const upb_inttable* t, uintptr_t* key, upb_value* val, + intptr_t* iter); +void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter); +void upb_inttable_setentryvalue(upb_inttable* t, intptr_t iter, upb_value v); +bool upb_inttable_done(const upb_inttable* t, intptr_t i); +uintptr_t upb_inttable_iter_key(const upb_inttable* t, intptr_t iter); +upb_value upb_inttable_iter_value(const upb_inttable* t, intptr_t iter); + +UPB_INLINE bool upb_inttable_arrhas(const upb_inttable* t, uintptr_t key) { + return (t->presence_mask[key / 8] & (1 << (key % 8))) != 0; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_INT_TABLE_H_ */ + +#ifndef UPB_HASH_STR_TABLE_H_ +#define UPB_HASH_STR_TABLE_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +typedef struct { + upb_table t; +} upb_strtable; + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize a table. If memory allocation failed, false is returned and +// the table is uninitialized. +bool upb_strtable_init(upb_strtable* table, size_t expected_size, upb_Arena* a); + +// Returns the number of values in the table. +UPB_INLINE size_t upb_strtable_count(const upb_strtable* t) { + return t->t.count; +} + +void upb_strtable_clear(upb_strtable* t); + +// Inserts the given key into the hashtable with the given value. +// The key must not already exist in the hash table. The key is not required +// to be NULL-terminated, and the table will make an internal copy of the key. +// +// If a table resize was required but memory allocation failed, false is +// returned and the table is unchanged. */ +bool upb_strtable_insert(upb_strtable* t, const char* key, size_t len, + upb_value val, upb_Arena* a); + +// Looks up key in this table, returning "true" if the key was found. +// If v is non-NULL, copies the value for this key into *v. +bool upb_strtable_lookup2(const upb_strtable* t, const char* key, size_t len, + upb_value* v); + +// For NULL-terminated strings. +UPB_INLINE bool upb_strtable_lookup(const upb_strtable* t, const char* key, + upb_value* v) { + return upb_strtable_lookup2(t, key, strlen(key), v); +} + +// Removes an item from the table. Returns true if the remove was successful, +// and stores the removed item in *val if non-NULL. +bool upb_strtable_remove2(upb_strtable* t, const char* key, size_t len, + upb_value* val); + +UPB_INLINE bool upb_strtable_remove(upb_strtable* t, const char* key, + upb_value* v) { + return upb_strtable_remove2(t, key, strlen(key), v); +} + +// Exposed for testing only. +bool upb_strtable_resize(upb_strtable* t, size_t size_lg2, upb_Arena* a); + +/* Iteration over strtable: + * + * intptr_t iter = UPB_STRTABLE_BEGIN; + * upb_StringView key; + * upb_value val; + * while (upb_strtable_next2(t, &key, &val, &iter)) { + * // ... + * } + */ + +#define UPB_STRTABLE_BEGIN -1 + +bool upb_strtable_next2(const upb_strtable* t, upb_StringView* key, + upb_value* val, intptr_t* iter); +void upb_strtable_removeiter(upb_strtable* t, intptr_t* iter); +void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v); + +/* DEPRECATED iterators, slated for removal. + * + * Iterators for string tables. We are subject to some kind of unusual + * design constraints: + * + * For high-level languages: + * - we must be able to guarantee that we don't crash or corrupt memory even if + * the program accesses an invalidated iterator. + * + * For C++11 range-based for: + * - iterators must be copyable + * - iterators must be comparable + * - it must be possible to construct an "end" value. + * + * Iteration order is undefined. + * + * Modifying the table invalidates iterators. upb_{str,int}table_done() is + * guaranteed to work even on an invalidated iterator, as long as the table it + * is iterating over has not been freed. Calling next() or accessing data from + * an invalidated iterator yields unspecified elements from the table, but it is + * guaranteed not to crash and to return real table elements (except when done() + * is true). */ +/* upb_strtable_iter **********************************************************/ + +/* upb_strtable_iter i; + * upb_strtable_begin(&i, t); + * for(; !upb_strtable_done(&i); upb_strtable_next(&i)) { + * const char *key = upb_strtable_iter_key(&i); + * const upb_value val = upb_strtable_iter_value(&i); + * // ... + * } + */ + +typedef struct { + const upb_strtable* t; + size_t index; +} upb_strtable_iter; + +UPB_INLINE const upb_tabent* str_tabent(const upb_strtable_iter* i) { + return &i->t->t.entries[i->index]; +} + +void upb_strtable_begin(upb_strtable_iter* i, const upb_strtable* t); +void upb_strtable_next(upb_strtable_iter* i); +bool upb_strtable_done(const upb_strtable_iter* i); +upb_StringView upb_strtable_iter_key(const upb_strtable_iter* i); +upb_value upb_strtable_iter_value(const upb_strtable_iter* i); +void upb_strtable_iter_setdone(upb_strtable_iter* i); +bool upb_strtable_iter_isequal(const upb_strtable_iter* i1, + const upb_strtable_iter* i2); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_STR_TABLE_H_ */ + +// Must be last. + +typedef enum { + kUpb_MapInsertStatus_Inserted = 0, + kUpb_MapInsertStatus_Replaced = 1, + kUpb_MapInsertStatus_OutOfMemory = 2, +} upb_MapInsertStatus; + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +union upb_Map_Table { + upb_strtable strtable; + upb_inttable inttable; +}; + +struct upb_Map { + // Size of key and val, based on the map type. + // Strings are represented as '0' because they must be handled specially. + char key_size; + char val_size; + bool UPB_PRIVATE(is_frozen); + bool UPB_PRIVATE(is_strtable); + + union upb_Map_Table t; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE void UPB_PRIVATE(_upb_Map_ShallowFreeze)(struct upb_Map* map) { + map->UPB_PRIVATE(is_frozen) = true; +} + +UPB_API_INLINE bool upb_Map_IsFrozen(const struct upb_Map* map) { + return map->UPB_PRIVATE(is_frozen); +} + +// Converting between internal table representation and user values. +// +// _upb_map_tokey() and _upb_map_fromkey() are inverses. +// _upb_map_tovalue() and _upb_map_fromvalue() are inverses. +// +// These functions account for the fact that strings are treated differently +// from other types when stored in a map. + +UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + return *(upb_StringView*)key; + } else { + return upb_StringView_FromDataAndSize((const char*)key, size); + } +} + +UPB_INLINE uintptr_t _upb_map_tointkey(const void* key, size_t key_size) { + uintptr_t intkey = 0; + memcpy(&intkey, key, key_size); + return intkey; +} + +UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + memcpy(out, &key, sizeof(key)); + } else { + memcpy(out, key.data, size); + } +} + +UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size, + upb_value* msgval, upb_Arena* a) { + if (size == UPB_MAPTYPE_STRING) { + upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp)); + if (!strp) return false; + *strp = *(upb_StringView*)val; + *msgval = upb_value_ptr(strp); + } else { + memcpy(msgval, val, size); + } + return true; +} + +UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) { + if (size == UPB_MAPTYPE_STRING) { + const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val); + memcpy(out, strp, sizeof(upb_StringView)); + } else { + memcpy(out, &val, size); + } +} + +UPB_INLINE bool _upb_map_next(const struct upb_Map* map, size_t* iter) { + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_iter it; + it.t = &map->t.strtable; + it.index = *iter; + upb_strtable_next(&it); + *iter = it.index; + return !upb_strtable_done(&it); + } else { + uintptr_t key; + upb_value val; + intptr_t int_iter = 0; + memcpy(&int_iter, iter, sizeof(intptr_t)); + upb_inttable_next(&map->t.inttable, &key, &val, &int_iter); + memcpy(iter, &int_iter, sizeof(size_t)); + return !upb_inttable_done(&map->t.inttable, int_iter); + } +} + +UPB_INLINE void _upb_Map_Clear(struct upb_Map* map) { + UPB_ASSERT(!upb_Map_IsFrozen(map)); + + if (map->UPB_PRIVATE(is_strtable)) { + upb_strtable_clear(&map->t.strtable); + } else { + upb_inttable_clear(&map->t.inttable); + } +} + +UPB_INLINE bool _upb_Map_Delete(struct upb_Map* map, const void* key, + size_t key_size, upb_value* val) { + UPB_ASSERT(!upb_Map_IsFrozen(map)); + + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView k = _upb_map_tokey(key, key_size); + return upb_strtable_remove2(&map->t.strtable, k.data, k.size, val); + } else { + uintptr_t intkey = _upb_map_tointkey(key, key_size); + return upb_inttable_remove(&map->t.inttable, intkey, val); + } +} + +UPB_INLINE bool _upb_Map_Get(const struct upb_Map* map, const void* key, + size_t key_size, void* val, size_t val_size) { + upb_value tabval = {0}; + bool ret; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView k = _upb_map_tokey(key, key_size); + ret = upb_strtable_lookup2(&map->t.strtable, k.data, k.size, &tabval); + } else { + uintptr_t intkey = _upb_map_tointkey(key, key_size); + ret = upb_inttable_lookup(&map->t.inttable, intkey, &tabval); + } + if (ret && val) { + _upb_map_fromvalue(tabval, val, val_size); + } + return ret; +} + +UPB_INLINE upb_MapInsertStatus _upb_Map_Insert(struct upb_Map* map, + const void* key, size_t key_size, + void* val, size_t val_size, + upb_Arena* a) { + UPB_ASSERT(!upb_Map_IsFrozen(map)); + + // Prep the value. + upb_value tabval = {0}; + if (!_upb_map_tovalue(val, val_size, &tabval, a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + + bool removed; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView strkey = _upb_map_tokey(key, key_size); + // TODO: add overwrite operation to minimize number of lookups. + removed = + upb_strtable_remove2(&map->t.strtable, strkey.data, strkey.size, NULL); + if (!upb_strtable_insert(&map->t.strtable, strkey.data, strkey.size, tabval, + a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + } else { + uintptr_t intkey = _upb_map_tointkey(key, key_size); + removed = upb_inttable_remove(&map->t.inttable, intkey, NULL); + if (!upb_inttable_insert(&map->t.inttable, intkey, tabval, a)) { + return kUpb_MapInsertStatus_OutOfMemory; + } + } + return removed ? kUpb_MapInsertStatus_Replaced + : kUpb_MapInsertStatus_Inserted; +} + +UPB_INLINE size_t _upb_Map_Size(const struct upb_Map* map) { + if (map->UPB_PRIVATE(is_strtable)) { + return map->t.strtable.t.count; + } else { + return upb_inttable_count(&map->t.inttable); + } +} + +// Strings/bytes are special-cased in maps. +extern char _upb_Map_CTypeSizeTable[12]; + +UPB_INLINE size_t _upb_Map_CTypeSize(upb_CType ctype) { + return (size_t)_upb_Map_CTypeSizeTable[ctype]; +} + +// Creates a new map on the given arena with this key/value type. +struct upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_MAP_H_ */ + +#ifndef UPB_MINI_TABLE_EXTENSION_H_ +#define UPB_MINI_TABLE_EXTENSION_H_ + +#include <stdint.h> + + +#ifndef UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ +#define UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +struct upb_MiniTableExtension { + // Do not move this field. We need to be able to alias pointers. + struct upb_MiniTableField UPB_PRIVATE(field); + + union upb_MiniTableSub UPB_PRIVATE(sub); // NULL unless submsg or proto2 enum + const struct upb_MiniTable* UPB_PRIVATE(extendee); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_CType +upb_MiniTableExtension_CType(const struct upb_MiniTableExtension* e) { + return upb_MiniTableField_CType(&e->UPB_PRIVATE(field)); +} + +UPB_API_INLINE uint32_t +upb_MiniTableExtension_Number(const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(field).UPB_ONLYBITS(number); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableExtension_Extendee( + const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(extendee); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableExtension_GetSubMessage( + const struct upb_MiniTableExtension* e) { + if (upb_MiniTableExtension_CType(e) != kUpb_CType_Message) { + return NULL; + } + return upb_MiniTableSub_Message(e->UPB_PRIVATE(sub)); +} + +UPB_API_INLINE const struct upb_MiniTableEnum* +upb_MiniTableExtension_GetSubEnum(const struct upb_MiniTableExtension* e) { + if (upb_MiniTableExtension_CType(e) != kUpb_CType_Enum) { + return NULL; + } + return upb_MiniTableSub_Enum(e->UPB_PRIVATE(sub)); +} + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubMessage( + struct upb_MiniTableExtension* e, const struct upb_MiniTable* m) { + if (e->UPB_PRIVATE(field).UPB_PRIVATE(descriptortype) != + kUpb_FieldType_Message && + e->UPB_PRIVATE(field).UPB_PRIVATE(descriptortype) != + kUpb_FieldType_Group) { + return false; + } + e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg) = m; + return true; +} + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubEnum( + struct upb_MiniTableExtension* e, const struct upb_MiniTableEnum* en) { + if (e->UPB_PRIVATE(field).UPB_PRIVATE(descriptortype) != + kUpb_FieldType_Enum) { + return false; + } + e->UPB_PRIVATE(sub).UPB_PRIVATE(subenum) = en; + return true; +} + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTableExtension_ToField( + const struct upb_MiniTableExtension* e) { + return &e->UPB_PRIVATE(field); +} + +UPB_INLINE upb_FieldRep UPB_PRIVATE(_upb_MiniTableExtension_GetRep)( + const struct upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableField_GetRep)(&e->UPB_PRIVATE(field)); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ */ + +// Must be last. + +typedef struct upb_MiniTableExtension upb_MiniTableExtension; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_CType +upb_MiniTableExtension_CType(const upb_MiniTableExtension* e); + +UPB_API_INLINE uint32_t +upb_MiniTableExtension_Number(const upb_MiniTableExtension* e); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableExtension_Extendee( + const upb_MiniTableExtension* e); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableExtension_GetSubMessage( + const upb_MiniTableExtension* e); + +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTableExtension_GetSubEnum( + const upb_MiniTableExtension* e); + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubMessage( + upb_MiniTableExtension* e, const upb_MiniTable* m); + +UPB_API_INLINE bool upb_MiniTableExtension_SetSubEnum( + upb_MiniTableExtension* e, const upb_MiniTableEnum* m); + +UPB_API_INLINE const upb_MiniTableField* upb_MiniTableExtension_ToField( + const upb_MiniTableExtension* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_EXTENSION_H_ */ + +// Must be last. + +// The internal representation of an extension is self-describing: it contains +// enough information that we can serialize it to binary format without needing +// to look it up in a upb_ExtensionRegistry. +// +// This representation allocates 16 bytes to data on 64-bit platforms. +// This is rather wasteful for scalars (in the extreme case of bool, +// it wastes 15 bytes). We accept this because we expect messages to be +// the most common extension type. +typedef struct { + const upb_MiniTableExtension* ext; + upb_MessageValue data; +} upb_Extension; + +#ifdef __cplusplus +extern "C" { +#endif + +// Adds the given extension data to the given message. +// |ext| is copied into the message instance. +// This logically replaces any previously-added extension with this number. +upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( + struct upb_Message* msg, const upb_MiniTableExtension* ext, + upb_Arena* arena); + +// Returns an extension for a message with a given mini table, +// or NULL if no extension exists with this mini table. +const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)( + const struct upb_Message* msg, const upb_MiniTableExtension* ext); + +UPB_INLINE bool UPB_PRIVATE(_upb_Extension_IsEmpty)(const upb_Extension* ext) { + switch ( + UPB_PRIVATE(_upb_MiniTableField_Mode)(&ext->ext->UPB_PRIVATE(field))) { + case kUpb_FieldMode_Scalar: + return false; + case kUpb_FieldMode_Array: + return upb_Array_Size(ext->data.array_val) == 0; + case kUpb_FieldMode_Map: + return _upb_Map_Size(ext->data.map_val) == 0; + } + UPB_UNREACHABLE(); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_EXTENSION_H_ */ + +/* +** Our memory representation for parsing tables and messages themselves. +** Functions in this file are used by generated code and possibly reflection. +** +** The definitions in this file are internal to upb. +**/ + +#ifndef UPB_MESSAGE_INTERNAL_MESSAGE_H_ +#define UPB_MESSAGE_INTERNAL_MESSAGE_H_ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +extern const float kUpb_FltInfinity; +extern const double kUpb_Infinity; +extern const double kUpb_NaN; + +// Internal members of a upb_Message that track unknown fields and/or +// extensions. We can change this without breaking binary compatibility. + +typedef struct upb_TaggedAuxPtr { + // Two lowest bits form a tag: + // 00 - non-aliased unknown data + // 10 - aliased unknown data + // 01 - extension + // + // The main semantic difference between aliased and non-aliased unknown data + // is that non-aliased unknown data can be assumed to have the following + // layout: + // + // [upb_StringView] [data] + // + // where the StringView points to the data buffer and the data buffer is + // immediately following the StringView. + // + // The string view does not necessarily point to the start of the data buffer; + // if the initial part of the buffer is removed from the message, the string + // view will point to the beginning of the remaining buffer. + // + // For aliased unknown data, this layout is _not_ guaranteed, since the + // pointer to the StringView can be anywhere in the allocation, and the + // StringView may point to non-data memory. + uintptr_t ptr; +} upb_TaggedAuxPtr; + +UPB_INLINE bool upb_TaggedAuxPtr_IsNull(upb_TaggedAuxPtr ptr) { + return ptr.ptr == 0; +} + +UPB_INLINE bool upb_TaggedAuxPtr_IsExtension(upb_TaggedAuxPtr ptr) { + return ptr.ptr & 1; +} + +UPB_INLINE bool upb_TaggedAuxPtr_IsUnknown(upb_TaggedAuxPtr ptr) { + return (ptr.ptr != 0) && ((ptr.ptr & 1) == 0); +} + +UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownAliased(upb_TaggedAuxPtr ptr) { + return (ptr.ptr != 0) && ((ptr.ptr & 2) == 2); +} + +UPB_INLINE upb_Extension* upb_TaggedAuxPtr_Extension(upb_TaggedAuxPtr ptr) { + UPB_ASSERT(upb_TaggedAuxPtr_IsExtension(ptr)); + return (upb_Extension*)(ptr.ptr & ~3ULL); +} + +UPB_INLINE upb_StringView* upb_TaggedAuxPtr_UnknownData(upb_TaggedAuxPtr ptr) { + UPB_ASSERT(!upb_TaggedAuxPtr_IsExtension(ptr)); + return (upb_StringView*)(ptr.ptr & ~3ULL); +} + +UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) { + upb_TaggedAuxPtr ptr; + ptr.ptr = 0; + return ptr; +} + +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeExtension(const upb_Extension* e) { + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)e | 1; + return ptr; +} + +// This tag means that the original allocation for this field starts with the +// string view and ends with the end of the content referenced by the string +// view. +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeUnknownData(const upb_StringView* sv) { + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)sv; + return ptr; +} + +// This tag implies no guarantee between the relationship of the string view and +// the data it points to. +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeUnknownDataAliased(const upb_StringView* sv) { + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)sv | 2; + return ptr; +} + +typedef struct upb_Message_Internal { + // Total number of entries set in aux_data + uint32_t size; + uint32_t capacity; + // Tagged pointers to upb_StringView or upb_Extension + upb_TaggedAuxPtr aux_data[]; +} upb_Message_Internal; + +#ifdef UPB_TRACING_ENABLED +UPB_API void upb_Message_LogNewMessage(const upb_MiniTable* m, + const upb_Arena* arena); +UPB_API void upb_Message_SetNewMessageTraceHandler( + void (*handler)(const upb_MiniTable*, const upb_Arena*)); +#endif // UPB_TRACING_ENABLED + +// Inline version upb_Message_New(), for internal use. +UPB_INLINE struct upb_Message* _upb_Message_New(const upb_MiniTable* m, + upb_Arena* a) { + UPB_PRIVATE(upb_MiniTable_CheckInvariants)(m); +#ifdef UPB_TRACING_ENABLED + upb_Message_LogNewMessage(m, a); +#endif // UPB_TRACING_ENABLED + + const size_t size = m->UPB_PRIVATE(size); + // Message sizes are aligned up when constructing minitables; telling the + // compiler this avoids redoing alignment on the malloc fast path + UPB_ASSUME(size % kUpb_Message_Align == 0); + struct upb_Message* msg = (struct upb_Message*)upb_Arena_Malloc(a, size); + if (UPB_UNLIKELY(!msg)) return NULL; + memset(msg, 0, size); + return msg; +} + +// Discards the unknown fields for this message only. +void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); + +UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)( + struct upb_Message* msg, const char* data, size_t len, upb_Arena* arena, + bool alias); + +typedef enum { + // Provided buffer is copied into the message. + kUpb_AddUnknown_Copy = 0, + + // The message will alias the provided buffer. + kUpb_AddUnknown_Alias = 1, + + // The message will alias the provided buffer, and we may merge the data with + // the immediately preceding unknown field if possible. + kUpb_AddUnknown_AliasAllowMerge = 2, +} upb_AddUnknownMode; + +// Adds unknown data (serialized protobuf data) to the given message. The data +// must represent one or more complete and well formed proto fields. +// +// If `alias_base` is NULL, the bytes from `data` will be copied into the +// destination arena. Otherwise it must be a pointer to the beginning of the +// buffer that `data` points into, which signals that the message must alias +// the bytes instead of copying them. The value of `alias_base` is also used +// to mark the boundary of the buffer, so that we do not inappropriately +// coalesce two buffers that are separate objects but happen to be contiguous +// in memory. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_AddUnknown)(struct upb_Message* msg, + const char* data, + size_t len, + upb_Arena* arena, + upb_AddUnknownMode mode) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (mode == kUpb_AddUnknown_AliasAllowMerge) { + // Aliasing parse of a message with sequential unknown fields is a simple + // pointer bump, so inline it. + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (in && in->size) { + upb_TaggedAuxPtr ptr = in->aux_data[in->size - 1]; + if (upb_TaggedAuxPtr_IsUnknown(ptr)) { + upb_StringView* existing = upb_TaggedAuxPtr_UnknownData(ptr); + // Fast path if the field we're adding is immediately after the last + // added unknown field. + // + // The caller has guaranteed to us, by passing + // kUpb_AddUnknown_AliasAllowMerge, that there is no risk that these two + // regions of memory are from different objects that are contiguous in + // memory by coincidence. + if (existing->data + existing->size == data) { + existing->size += len; + return true; + } + } + } + } + return UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)( + msg, data, len, arena, mode != kUpb_AddUnknown_Copy); +} + +// Adds unknown data (serialized protobuf data) to the given message. +// The data is copied into the message instance. Data when concatenated together +// must represent one or more complete and well formed proto fields, but the +// individual spans may point only to partial fields. +bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, + upb_Arena* arena, + upb_StringView data[], size_t count); + +// Ensures at least one slot is available in the aux_data of this message. +// Returns false if a reallocation is needed to satisfy the request, and fails. +bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg, + upb_Arena* arena); + +#define kUpb_Message_UnknownBegin 0 +#define kUpb_Message_ExtensionBegin 0 + +UPB_INLINE bool upb_Message_NextUnknown(const struct upb_Message* msg, + upb_StringView* data, uintptr_t* iter) { + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + size_t i = *iter; + if (in) { + while (i < in->size) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i++]; + if (upb_TaggedAuxPtr_IsUnknown(tagged_ptr)) { + *data = *upb_TaggedAuxPtr_UnknownData(tagged_ptr); + *iter = i; + return true; + } + } + } + data->size = 0; + data->data = NULL; + *iter = i; + return false; +} + +UPB_INLINE bool upb_Message_HasUnknown(const struct upb_Message* msg) { + upb_StringView data; + uintptr_t iter = kUpb_Message_UnknownBegin; + return upb_Message_NextUnknown(msg, &data, &iter); +} + +UPB_INLINE bool upb_Message_NextExtension(const struct upb_Message* msg, + const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, + uintptr_t* iter) { + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + uintptr_t i = *iter; + if (in) { + while (i < in->size) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i++]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + + // Empty repeated fields or maps semantically don't exist. + if (UPB_PRIVATE(_upb_Extension_IsEmpty)(ext)) continue; + + *out_e = ext->ext; + *out_v = ext->data; + *iter = i; + return true; + } + } + } + *iter = i; + + return false; +} + +UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( + const struct upb_Message* msg, const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, uintptr_t* iter) { + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return false; + uintptr_t i = *iter; + uint32_t size = in->size; + while (i < size) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[size - 1 - i]; + i++; + if (!upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + continue; + } + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + + // Empty repeated fields or maps semantically don't exist. + if (UPB_PRIVATE(_upb_Extension_IsEmpty)(ext)) continue; + + *out_e = ext->ext; + *out_v = ext->data; + *iter = i; + return true; + } + *iter = i; + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_MESSAGE_H_ */ + +// Must be last. + +#if defined(__GNUC__) && !defined(__clang__) +// GCC raises incorrect warnings in these functions. It thinks that we are +// overrunning buffers, but we carefully write the functions in this file to +// guarantee that this is impossible. GCC gets this wrong due it its failure +// to perform constant propagation as we expect: +// - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108217 +// - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108226 +// +// Unfortunately this also indicates that GCC is not optimizing away the +// switch() in cases where it should be, compromising the performance. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#if __GNUC__ >= 11 +#pragma GCC diagnostic ignored "-Wstringop-overread" +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// LINT.IfChange(presence_logic) + +// Hasbit access /////////////////////////////////////////////////////////////// + +UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbit)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); + const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); + + return (*UPB_PTR_AT(msg, offset, const char) & mask) != 0; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); + const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); + + (*UPB_PTR_AT(msg, offset, char)) |= mask; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_ClearHasbit)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); + const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); + + (*UPB_PTR_AT(msg, offset, char)) &= ~mask; +} + +// Oneof case access /////////////////////////////////////////////////////////// + +UPB_INLINE uint32_t* UPB_PRIVATE(_upb_Message_OneofCasePtr)( + struct upb_Message* msg, const upb_MiniTableField* f) { + return UPB_PTR_AT(msg, UPB_PRIVATE(_upb_MiniTableField_OneofOffset)(f), + uint32_t); +} + +UPB_INLINE uint32_t UPB_PRIVATE(_upb_Message_GetOneofCase)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + const uint32_t* ptr = + UPB_PRIVATE(_upb_Message_OneofCasePtr)((struct upb_Message*)msg, f); + + return *ptr; +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetOneofCase)( + struct upb_Message* msg, const upb_MiniTableField* f) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f); + + *ptr = upb_MiniTableField_Number(f); +} + +// Returns true if the given field is the current oneof case. +// Does nothing if it is not the current oneof case. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_ClearOneofCase)( + struct upb_Message* msg, const upb_MiniTableField* f) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f); + + if (*ptr != upb_MiniTableField_Number(f)) return false; + *ptr = 0; + return true; +} + +UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( + const struct upb_Message* message, const upb_MiniTableField* oneof_field) { + UPB_ASSUME(upb_MiniTableField_IsInOneof(oneof_field)); + return UPB_PRIVATE(_upb_Message_GetOneofCase)(message, oneof_field); +} + +UPB_API_INLINE const upb_MiniTableField* upb_Message_WhichOneof( + const struct upb_Message* msg, const upb_MiniTable* m, + const upb_MiniTableField* f) { + uint32_t field_number = upb_Message_WhichOneofFieldNumber(msg, f); + if (field_number == 0) { + // No field in the oneof is set. + return NULL; + } + return upb_MiniTable_FindFieldByNumber(m, field_number); +} + +// LINT.ThenChange(GoogleInternalName2) + +// Returns false if the message is missing any of its required fields. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_IsInitializedShallow)( + const struct upb_Message* msg, const upb_MiniTable* m) { + uint64_t bits; + memcpy(&bits, msg + 1, sizeof(bits)); + bits = upb_BigEndian64(bits); + return (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~bits) == 0; +} + +UPB_INLINE void* UPB_PRIVATE(_upb_Message_MutableDataPtr)( + struct upb_Message* msg, const upb_MiniTableField* f) { + return (char*)msg + f->UPB_ONLYBITS(offset); +} + +UPB_INLINE const void* UPB_PRIVATE(_upb_Message_DataPtr)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + return (const char*)msg + f->UPB_ONLYBITS(offset); +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetPresence)( + struct upb_Message* msg, const upb_MiniTableField* f) { + if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, f); + } else if (upb_MiniTableField_IsInOneof(f)) { + UPB_PRIVATE(_upb_Message_SetOneofCase)(msg, f); + } +} + +UPB_INLINE_IF_NOT_GCC void UPB_PRIVATE(_upb_MiniTableField_DataCopy)( + const upb_MiniTableField* f, void* to, const void* from) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: + memcpy(to, from, 1); + return; + case kUpb_FieldRep_4Byte: + memcpy(to, from, 4); + return; + case kUpb_FieldRep_8Byte: + memcpy(to, from, 8); + return; + case kUpb_FieldRep_StringView: { + memcpy(to, from, sizeof(upb_StringView)); + return; + } + } + UPB_UNREACHABLE(); +} + +UPB_INLINE_IF_NOT_GCC bool UPB_PRIVATE(_upb_MiniTableField_DataEquals)( + const upb_MiniTableField* f, const void* a, const void* b) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: + return memcmp(a, b, 1) == 0; + case kUpb_FieldRep_4Byte: + return memcmp(a, b, 4) == 0; + case kUpb_FieldRep_8Byte: + return memcmp(a, b, 8) == 0; + case kUpb_FieldRep_StringView: { + const upb_StringView sa = *(const upb_StringView*)a; + const upb_StringView sb = *(const upb_StringView*)b; + return upb_StringView_IsEqual(sa, sb); + } + } + UPB_UNREACHABLE(); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_DataClear)( + const upb_MiniTableField* f, void* val) { + const char zero[16] = {0}; + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, zero); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataIsZero)( + const upb_MiniTableField* f, const void* val) { + const char zero[16] = {0}; + return UPB_PRIVATE(_upb_MiniTableField_DataEquals)(f, val, zero); +} + +// Here we define universal getter/setter functions for message fields. +// These look very branchy and inefficient, but as long as the MiniTableField +// values are known at compile time, all the branches are optimized away and +// we are left with ideal code. This can happen either through through +// literals or UPB_ASSUME(): +// +// // Via struct literals. +// bool FooMessage_set_bool_field(const upb_Message* msg, bool val) { +// const upb_MiniTableField field = {1, 0, 0, /* etc... */}; +// // All value in "field" are compile-time known. +// upb_Message_SetBaseField(msg, &field, &value); +// } +// +// // Via UPB_ASSUME(). +// UPB_INLINE bool upb_Message_SetBool(upb_Message* msg, +// const upb_MiniTableField* field, +// bool value, upb_Arena* a) { +// UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool); +// UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == +// kUpb_FieldRep_1Byte); +// upb_Message_SetField(msg, field, &value, a); +// } +// +// As a result, we can use these universal getters/setters for *all* message +// accessors: generated code, MiniTable accessors, and reflection. The only +// exception is the binary encoder/decoder, which need to be a bit more clever +// about how they read/write the message data, for efficiency. +// +// These functions work on both extensions and non-extensions. If the field +// of a setter is known to be a non-extension, the arena may be NULL and the +// returned bool value may be ignored since it will always succeed. + +UPB_API_INLINE bool upb_Message_HasBaseField(const struct upb_Message* msg, + const upb_MiniTableField* field) { + UPB_ASSERT(upb_MiniTableField_HasPresence(field)); + UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); + if (upb_MiniTableField_IsInOneof(field)) { + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, field) == + upb_MiniTableField_Number(field); + } else { + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, field); + } +} + +UPB_API_INLINE bool upb_Message_HasExtension(const struct upb_Message* msg, + const upb_MiniTableExtension* e) { + UPB_ASSERT(upb_MiniTableField_HasPresence(&e->UPB_PRIVATE(field))); + return UPB_PRIVATE(_upb_Message_Getext)(msg, e) != NULL; +} + +UPB_FORCEINLINE void _upb_Message_GetNonExtensionField( + const struct upb_Message* msg, const upb_MiniTableField* field, + const void* default_val, void* val) { + UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); + if ((upb_MiniTableField_IsInOneof(field) || + !UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, default_val)) && + !upb_Message_HasBaseField(msg, field)) { + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(field, val, default_val); + return; + } + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, val, UPB_PRIVATE(_upb_Message_DataPtr)(msg, field)); +} + +UPB_INLINE void _upb_Message_GetExtensionField( + const struct upb_Message* msg, const upb_MiniTableExtension* mt_ext, + const void* default_val, void* val) { + const upb_Extension* ext = UPB_PRIVATE(_upb_Message_Getext)(msg, mt_ext); + const upb_MiniTableField* f = &mt_ext->UPB_PRIVATE(field); + UPB_ASSUME(upb_MiniTableField_IsExtension(f)); + + if (ext) { + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, &ext->data); + } else { + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, default_val); + } +} + +// NOTE: The default_val is only used for fields that support presence. +// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a +// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have +// presence, so this is semantically identical to a pointer to an empty +// array/map, and must be treated the same for all semantic purposes. +UPB_API_INLINE upb_MessageValue upb_Message_GetField( + const struct upb_Message* msg, const upb_MiniTableField* field, + upb_MessageValue default_val) { + upb_MessageValue ret; + if (upb_MiniTableField_IsExtension(field)) { + _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, + &default_val, &ret); + } else { + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); + } + return ret; +} + +UPB_API_INLINE void upb_Message_SetBaseField(struct upb_Message* msg, + const upb_MiniTableField* f, + const void* val) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSUME(!upb_MiniTableField_IsExtension(f)); + UPB_PRIVATE(_upb_Message_SetPresence)(msg, f); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), val); +} + +UPB_API_INLINE bool upb_Message_SetExtension(struct upb_Message* msg, + const upb_MiniTableExtension* e, + const void* val, upb_Arena* a) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSERT(a); + upb_Extension* ext = + UPB_PRIVATE(_upb_Message_GetOrCreateExtension)(msg, e, a); + if (!ext) return false; + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (&e->UPB_PRIVATE(field), &ext->data, val); + return true; +} + +// Sets the value of the given field in the given msg. The return value is true +// if the operation completed successfully, or false if memory allocation +// failed. +UPB_INLINE bool UPB_PRIVATE(_upb_Message_SetField)(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_MessageValue val, + upb_Arena* a) { + if (upb_MiniTableField_IsExtension(f)) { + const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)f; + return upb_Message_SetExtension(msg, ext, &val, a); + } else { + upb_Message_SetBaseField(msg, f, &val); + return true; + } +} + +UPB_API_INLINE const upb_Array* upb_Message_GetArray( + const struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_Array* ret; + const upb_Array* default_val = NULL; + _upb_Message_GetNonExtensionField(msg, f, &default_val, &ret); + return ret; +} + +UPB_API_INLINE bool upb_Message_GetBool(const struct upb_Message* msg, + const upb_MiniTableField* f, + bool default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Bool); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_1Byte); + upb_MessageValue def; + def.bool_val = default_val; + return upb_Message_GetField(msg, f, def).bool_val; +} + +UPB_API_INLINE double upb_Message_GetDouble(const struct upb_Message* msg, + const upb_MiniTableField* f, + double default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Double); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + + upb_MessageValue def; + def.double_val = default_val; + return upb_Message_GetField(msg, f, def).double_val; +} + +UPB_API_INLINE float upb_Message_GetFloat(const struct upb_Message* msg, + const upb_MiniTableField* f, + float default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Float); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + + upb_MessageValue def; + def.float_val = default_val; + return upb_Message_GetField(msg, f, def).float_val; +} + +UPB_API_INLINE int32_t upb_Message_GetInt32(const struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int32 || + upb_MiniTableField_CType(f) == kUpb_CType_Enum); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + + upb_MessageValue def; + def.int32_val = default_val; + return upb_Message_GetField(msg, f, def).int32_val; +} + +UPB_API_INLINE int64_t upb_Message_GetInt64(const struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + + upb_MessageValue def; + def.int64_val = default_val; + return upb_Message_GetField(msg, f, def).int64_val; +} + +UPB_API_INLINE const struct upb_Map* upb_Message_GetMap( + const struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(f); + struct upb_Map* ret; + const struct upb_Map* default_val = NULL; + _upb_Message_GetNonExtensionField(msg, f, &default_val, &ret); + return ret; +} + +UPB_API_INLINE const struct upb_Message* upb_Message_GetMessage( + const struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + upb_MessageValue def; + def.msg_val = NULL; + return upb_Message_GetField(msg, f, def).msg_val; +} + +UPB_API_INLINE upb_Array* upb_Message_GetMutableArray( + struct upb_Message* msg, const upb_MiniTableField* f) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + return (upb_Array*)upb_Message_GetArray(msg, f); +} + +UPB_API_INLINE struct upb_Map* upb_Message_GetMutableMap( + struct upb_Message* msg, const upb_MiniTableField* f) { + return (struct upb_Map*)upb_Message_GetMap(msg, f); +} + +UPB_API_INLINE struct upb_Message* upb_Message_GetMutableMessage( + struct upb_Message* msg, const upb_MiniTableField* f) { + return (struct upb_Message*)upb_Message_GetMessage(msg, f); +} + +UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( + struct upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena) { + UPB_ASSERT(arena); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_Array* array = upb_Message_GetMutableArray(msg, f); + if (!array) { + array = UPB_PRIVATE(_upb_Array_New)( + arena, 4, UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)(f)); + // Check again due to: https://godbolt.org/z/7WfaoKG1r + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_MessageValue val; + val.array_val = array; + UPB_PRIVATE(_upb_Message_SetField)(msg, f, val, arena); + } + return array; +} + +UPB_INLINE struct upb_Map* _upb_Message_GetOrCreateMutableMap( + struct upb_Message* msg, const upb_MiniTableField* field, size_t key_size, + size_t val_size, upb_Arena* arena) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); + struct upb_Map* map = NULL; + struct upb_Map* default_map_value = NULL; + _upb_Message_GetNonExtensionField(msg, field, &default_map_value, &map); + if (!map) { + map = _upb_Map_New(arena, key_size, val_size); + // Check again due to: https://godbolt.org/z/7WfaoKG1r + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); + upb_Message_SetBaseField(msg, field, &map); + } + return map; +} + +UPB_API_INLINE struct upb_Map* upb_Message_GetOrCreateMutableMap( + struct upb_Message* msg, const upb_MiniTable* map_entry_mini_table, + const upb_MiniTableField* f, upb_Arena* arena) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + const upb_MiniTableField* map_entry_key_field = + &map_entry_mini_table->UPB_ONLYBITS(fields)[0]; + const upb_MiniTableField* map_entry_value_field = + &map_entry_mini_table->UPB_ONLYBITS(fields)[1]; + return _upb_Message_GetOrCreateMutableMap( + msg, f, _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)), + _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_value_field)), + arena); +} + +UPB_API_INLINE struct upb_Message* upb_Message_GetOrCreateMutableMessage( + struct upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena) { + UPB_ASSERT(arena); + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + UPB_ASSUME(!upb_MiniTableField_IsExtension(f)); + struct upb_Message* sub_message = + *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*); + if (!sub_message) { + const upb_MiniTable* sub_mini_table = upb_MiniTable_SubMessage(f); + UPB_ASSERT(sub_mini_table); + sub_message = _upb_Message_New(sub_mini_table, arena); + *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*) = + sub_message; + UPB_PRIVATE(_upb_Message_SetPresence)(msg, f); + } + return sub_message; +} + +UPB_API_INLINE upb_StringView +upb_Message_GetString(const struct upb_Message* msg, + const upb_MiniTableField* f, upb_StringView default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_String || + upb_MiniTableField_CType(f) == kUpb_CType_Bytes); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_StringView); + + upb_MessageValue def; + def.str_val = default_val; + return upb_Message_GetField(msg, f, def).str_val; +} + +UPB_API_INLINE uint32_t upb_Message_GetUInt32(const struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt32); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + + upb_MessageValue def; + def.uint32_val = default_val; + return upb_Message_GetField(msg, f, def).uint32_val; +} + +UPB_API_INLINE uint64_t upb_Message_GetUInt64(const struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t default_val) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + + upb_MessageValue def; + def.uint64_val = default_val; + return upb_Message_GetField(msg, f, def).uint64_val; +} + +// BaseField Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE void upb_Message_SetBaseFieldBool(struct upb_Message* msg, + const upb_MiniTableField* f, + bool value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Bool); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_1Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldDouble(struct upb_Message* msg, + const upb_MiniTableField* f, + double value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Double); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldFloat(struct upb_Message* msg, + const upb_MiniTableField* f, + float value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Float); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int32 || + upb_MiniTableField_CType(f) == kUpb_CType_Enum); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Int64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldMessage(struct upb_Message* msg, + const upb_MiniTableField* f, + struct upb_Message* value) { + // TODO - Re-enable this assertion. + // UPB_ASSERT(value); + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldString(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_String || + upb_MiniTableField_CType(f) == kUpb_CType_Bytes); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_StringView); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt32); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value) { + UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_UInt64); + UPB_ASSUME(upb_MiniTableField_IsScalar(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_8Byte); + upb_Message_SetBaseField(msg, f, &value); +} + +UPB_API_INLINE void upb_Message_SetClosedEnum(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value) { + UPB_ASSERT(upb_MiniTableField_IsClosedEnum(f)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte); + UPB_ASSERT(upb_MiniTableEnum_CheckValue(upb_MiniTable_GetSubEnumTable(f), + (uint32_t)value)); + upb_Message_SetBaseField(msg, f, &value); +} + +// Extension Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetExtensionMessage( + struct upb_Message* msg, const upb_MiniTableExtension* e, + struct upb_Message* value, upb_Arena* a) { + UPB_ASSERT(value); + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionBool( + struct upb_Message* msg, const upb_MiniTableExtension* e, bool value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Bool); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_1Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionDouble( + struct upb_Message* msg, const upb_MiniTableExtension* e, double value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Double); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionFloat( + struct upb_Message* msg, const upb_MiniTableExtension* e, float value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Float); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, int32_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int32 || + upb_MiniTableExtension_CType(e) == kUpb_CType_Enum); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, int64_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionString( + struct upb_Message* msg, const upb_MiniTableExtension* e, + upb_StringView value, upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_String || + upb_MiniTableExtension_CType(e) == kUpb_CType_Bytes); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_StringView); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionUInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint32_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt32); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +UPB_API_INLINE bool upb_Message_SetExtensionUInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint64_t value, + upb_Arena* a) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + return upb_Message_SetExtension(msg, e, &value, a); +} + +// Universal Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetBool(struct upb_Message* msg, + const upb_MiniTableField* f, bool value, + upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionBool( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldBool(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetDouble(struct upb_Message* msg, + const upb_MiniTableField* f, + double value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionDouble( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldDouble(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetFloat(struct upb_Message* msg, + const upb_MiniTableField* f, + float value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionFloat( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldFloat(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionInt32( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldInt32(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionInt64( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldInt64(msg, f, value), true); +} + +// Sets the value of a message-typed field. The mini_tables of `msg` and +// `value` must have been linked for this to work correctly. +UPB_API_INLINE void upb_Message_SetMessage(struct upb_Message* msg, + const upb_MiniTableField* f, + struct upb_Message* value) { + UPB_ASSERT(!upb_MiniTableField_IsExtension(f)); + upb_Message_SetBaseFieldMessage(msg, f, value); +} + +// Sets the value of a `string` or `bytes` field. The bytes of the value are not +// copied, so it is the caller's responsibility to ensure that they remain valid +// for the lifetime of `msg`. That might be done by copying them into the given +// arena, or by fusing that arena with the arena the bytes live in, for example. +UPB_API_INLINE bool upb_Message_SetString(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionString( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldString(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetUInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionUInt32( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldUInt32(msg, f, value), true); +} + +UPB_API_INLINE bool upb_Message_SetUInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value, upb_Arena* a) { + return upb_MiniTableField_IsExtension(f) + ? upb_Message_SetExtensionUInt64( + msg, (const upb_MiniTableExtension*)f, value, a) + : (upb_Message_SetBaseFieldUInt64(msg, f, value), true); +} + +UPB_API_INLINE void upb_Message_Clear(struct upb_Message* msg, + const upb_MiniTable* m) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + memset(msg, 0, m->UPB_PRIVATE(size)); + if (in) { + // Reset the internal buffer to empty. + in->size = 0; + } +} + +UPB_API_INLINE void upb_Message_ClearBaseField(struct upb_Message* msg, + const upb_MiniTableField* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + UPB_PRIVATE(_upb_Message_ClearHasbit)(msg, f); + } else if (upb_MiniTableField_IsInOneof(f)) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f); + if (*ptr != upb_MiniTableField_Number(f)) return; + *ptr = 0; + } + const char zeros[16] = {0}; + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), zeros); +} + +UPB_API_INLINE void upb_Message_ClearExtension( + struct upb_Message* msg, const upb_MiniTableExtension* e) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!in) return; + for (size_t i = 0; i < in->size; i++) { + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + if (ext->ext == e) { + in->aux_data[i] = upb_TaggedAuxPtr_Null(); + return; + } + } + } +} + +UPB_API_INLINE void upb_Message_ClearOneof(struct upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField* f) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + uint32_t field_number = upb_Message_WhichOneofFieldNumber(msg, f); + if (field_number == 0) { + // No field in the oneof is set. + return; + } + + const upb_MiniTableField* field = + upb_MiniTable_FindFieldByNumber(m, field_number); + upb_Message_ClearBaseField(msg, field); +} + +UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( + struct upb_Message* msg, const upb_MiniTableField* f, size_t size, + upb_Arena* arena) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(msg, f, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, size, arena)) { + return NULL; + } + return upb_Array_MutableDataPtr(arr); +} + +UPB_API_INLINE bool upb_Message_GetExtensionBool( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + bool default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Bool); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_1Byte); + bool ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE double upb_Message_GetExtensionDouble( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + double default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Double); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + double ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE float upb_Message_GetExtensionFloat( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + float default_val) { + float ret; + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Float); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE int32_t upb_Message_GetExtensionInt32( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + int32_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int32 || + upb_MiniTableExtension_CType(e) == kUpb_CType_Enum); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + int32_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE int64_t upb_Message_GetExtensionInt64( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + int64_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Int64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + int64_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE uint32_t upb_Message_GetExtensionUInt32( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + uint32_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt32); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_4Byte); + uint32_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE uint64_t upb_Message_GetExtensionUInt64( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + uint64_t default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_UInt64); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_8Byte); + uint64_t ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE upb_StringView upb_Message_GetExtensionString( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + upb_StringView default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_String || + upb_MiniTableExtension_CType(e) == kUpb_CType_Bytes); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + kUpb_FieldRep_StringView); + upb_StringView ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE struct upb_Message* upb_Message_GetExtensionMessage( + const struct upb_Message* msg, const upb_MiniTableExtension* e, + struct upb_Message* default_val) { + UPB_ASSUME(upb_MiniTableExtension_CType(e) == kUpb_CType_Message); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableExtension_GetRep)(e) == + UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + struct upb_Message* ret; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +// Repeated +UPB_API_INLINE const upb_Array* upb_Message_GetExtensionArray( + const struct upb_Message* msg, const upb_MiniTableExtension* e) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(&e->UPB_PRIVATE(field)) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsArray(&e->UPB_PRIVATE(field))); + UPB_ASSUME(e->UPB_PRIVATE(field).presence == 0); + upb_Array* ret; + const upb_Array* default_val = NULL; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +UPB_API_INLINE upb_Array* upb_Message_GetExtensionMutableArray( + struct upb_Message* msg, const upb_MiniTableExtension* e) { + UPB_ASSERT(!upb_Message_IsFrozen(msg)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(&e->UPB_PRIVATE(field)) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(upb_MiniTableField_IsArray(&e->UPB_PRIVATE(field))); + UPB_ASSUME(e->UPB_PRIVATE(field).presence == 0); + upb_Array* ret; + upb_Array* default_val = NULL; + _upb_Message_GetExtensionField(msg, e, &default_val, &ret); + return ret; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + +#endif // UPB_MESSAGE_INTERNAL_ACCESSORS_H_ + +#ifndef UPB_MESSAGE_MAP_H_ +#define UPB_MESSAGE_MAP_H_ + +#include <stddef.h> + + +// Must be last. + +typedef struct upb_Map upb_Map; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates a new map on the given arena with the given key/value size. +UPB_API upb_Map* upb_Map_New(upb_Arena* a, upb_CType key_type, + upb_CType value_type); + +// Returns the number of entries in the map. +UPB_API size_t upb_Map_Size(const upb_Map* map); + +// Stores a value for the given key into |*val| (or the zero value if the key is +// not present). Returns whether the key was present. The |val| pointer may be +// NULL, in which case the function tests whether the given key is present. +UPB_API bool upb_Map_Get(const upb_Map* map, upb_MessageValue key, + upb_MessageValue* val); + +// Returns a mutable pointer to the value for the given key. Returns NULL if the +// key is not present. +// This function is only legal to call for maps that contain messages. +UPB_API struct upb_Message* upb_Map_GetMutable(upb_Map* map, + upb_MessageValue key); + +// Removes all entries in the map. +UPB_API void upb_Map_Clear(upb_Map* map); + +// Sets the given key to the given value, returning whether the key was inserted +// or replaced. If the key was inserted, then any existing iterators will be +// invalidated. +UPB_API upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key, + upb_MessageValue val, + upb_Arena* arena); + +// Sets the given key to the given value. Returns false if memory allocation +// failed. If the key is newly inserted, then any existing iterators will be +// invalidated. +UPB_API_INLINE bool upb_Map_Set(upb_Map* map, upb_MessageValue key, + upb_MessageValue val, upb_Arena* arena) { + return upb_Map_Insert(map, key, val, arena) != + kUpb_MapInsertStatus_OutOfMemory; +} + +// Deletes this key from the table. Returns true if the key was present. +// If present and |val| is non-NULL, stores the deleted value. +UPB_API bool upb_Map_Delete(upb_Map* map, upb_MessageValue key, + upb_MessageValue* val); + +// Map iteration: +// +// size_t iter = kUpb_Map_Begin; +// upb_MessageValue key, val; +// while (upb_Map_Next(map, &key, &val, &iter)) { +// ... +// } + +#define kUpb_Map_Begin ((size_t)-1) + +// Advances to the next entry. Returns false if no more entries are present. +// Otherwise returns true and populates both *key and *value. +UPB_API bool upb_Map_Next(const upb_Map* map, upb_MessageValue* key, + upb_MessageValue* val, size_t* iter); + +// Sets the value for the entry pointed to by iter. +// WARNING: this does not currently work for string values! +UPB_API void upb_Map_SetEntryValue(upb_Map* map, size_t iter, + upb_MessageValue val); + +// DEPRECATED iterator, slated for removal. + +/* Map iteration: + * + * size_t iter = kUpb_Map_Begin; + * while (upb_MapIterator_Next(map, &iter)) { + * upb_MessageValue key = upb_MapIterator_Key(map, iter); + * upb_MessageValue val = upb_MapIterator_Value(map, iter); + * } + */ + +// Advances to the next entry. Returns false if no more entries are present. +UPB_API bool upb_MapIterator_Next(const upb_Map* map, size_t* iter); + +// Returns true if the iterator still points to a valid entry, or false if the +// iterator is past the last element. It is an error to call this function with +// kUpb_Map_Begin (you must call next() at least once first). +UPB_API bool upb_MapIterator_Done(const upb_Map* map, size_t iter); + +// Returns the key and value for this entry of the map. +UPB_API upb_MessageValue upb_MapIterator_Key(const upb_Map* map, size_t iter); +UPB_API upb_MessageValue upb_MapIterator_Value(const upb_Map* map, size_t iter); + +// Mark a map and all of its descendents as frozen/immutable. +// If the map values are messages then |m| must point to the minitable for +// those messages. Otherwise |m| must be NULL. +UPB_API void upb_Map_Freeze(upb_Map* map, const upb_MiniTable* m); + +// Returns whether a map has been frozen. +UPB_API_INLINE bool upb_Map_IsFrozen(const upb_Map* map); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_MAP_H_ */ + +// Public APIs for message operations that do not depend on the schema. +// +// MiniTable-based accessors live in accessors.h. + +#ifndef UPB_MESSAGE_MESSAGE_H_ +#define UPB_MESSAGE_MESSAGE_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +typedef struct upb_Message upb_Message; + +#ifdef __cplusplus +extern "C" { +#endif + +// Creates a new message with the given mini_table on the given arena. +UPB_API upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena); + +// +// Unknown data may be stored non-contiguously. Each segment stores a block of +// unknown fields. To iterate over segments: +// +// uintptr_t iter = kUpb_Message_UnknownBegin; +// upb_StringView data; +// while (upb_Message_NextUnknown(msg, &data, &iter)) { +// // Use data +// } +// Iterates in the order unknown fields were parsed. + +#define kUpb_Message_UnknownBegin 0 +#define kUpb_Message_ExtensionBegin 0 + +UPB_INLINE bool upb_Message_NextUnknown(const upb_Message* msg, + upb_StringView* data, uintptr_t* iter); + +UPB_INLINE bool upb_Message_HasUnknown(const upb_Message* msg); + +// Removes a segment of unknown data from the message, advancing to the next +// segment. Returns false if the removed segment was at the end of the last +// chunk. +// +// This must be done while iterating: +// +// uintptr_t iter = kUpb_Message_UnknownBegin; +// upb_StringView data; +// // Iterate chunks +// while (upb_Message_NextUnknown(msg, &data, &iter)) { +// // Iterate within a chunk, deleting ranges +// while (ShouldDeleteSubSegment(&data)) { +// // Data now points to the region to be deleted +// switch (upb_Message_DeleteUnknown(msg, &data, &iter)) { +// case kUpb_Message_DeleteUnknown_DeletedLast: return ok; +// case kUpb_Message_DeleteUnknown_IterUpdated: break; +// // If DeleteUnknown returned kUpb_Message_DeleteUnknown_IterUpdated, +// // then data now points to the remaining unknown fields after the +// // region that was just deleted. +// case kUpb_Message_DeleteUnknown_AllocFail: return err; +// } +// } +// } +// +// The range given in `data` must be contained inside the most recently +// returned region. +typedef enum upb_Message_DeleteUnknownStatus { + kUpb_DeleteUnknown_DeletedLast, + kUpb_DeleteUnknown_IterUpdated, + kUpb_DeleteUnknown_AllocFail, +} upb_Message_DeleteUnknownStatus; +upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg, + upb_StringView* data, + uintptr_t* iter, + upb_Arena* arena); + +// Returns the number of extensions present in this message. +size_t upb_Message_ExtensionCount(const upb_Message* msg); + +// Iterates extensions in wire order +UPB_INLINE bool upb_Message_NextExtension(const upb_Message* msg, + const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, + uintptr_t* iter); + +// Iterates extensions in reverse wire order +UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( + const struct upb_Message* msg, const upb_MiniTableExtension** out_e, + upb_MessageValue* out_v, uintptr_t* iter); + +// Mark a message and all of its descendents as frozen/immutable. +UPB_API void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m); + +// Returns whether a message has been frozen. +UPB_API_INLINE bool upb_Message_IsFrozen(const upb_Message* msg); + +#ifdef UPB_TRACING_ENABLED +UPB_API void upb_Message_LogNewMessage(const upb_MiniTable* m, + const upb_Arena* arena); + +UPB_API void upb_Message_SetNewMessageTraceHandler( + void (*handler)(const upb_MiniTable* m, const upb_Arena* arena)); +#endif // UPB_TRACING_ENABLED + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_MESSAGE_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Functions ending in BaseField() take a (upb_MiniTableField*) argument +// and work only on non-extension fields. +// +// Functions ending in Extension() take a (upb_MiniTableExtension*) argument +// and work only on extensions. + +UPB_API_INLINE void upb_Message_Clear(upb_Message* msg, const upb_MiniTable* m); + +UPB_API_INLINE void upb_Message_ClearBaseField(upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE void upb_Message_ClearExtension(upb_Message* msg, + const upb_MiniTableExtension* e); + +UPB_API_INLINE void upb_Message_ClearOneof(upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_Message_HasBaseField(const upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_Message_HasExtension(const upb_Message* msg, + const upb_MiniTableExtension* e); + +UPB_API_INLINE upb_MessageValue +upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* f, + upb_MessageValue default_val); + +UPB_API_INLINE const upb_Array* upb_Message_GetArray( + const upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg, + const upb_MiniTableField* f, + bool default_val); + +UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, + const upb_MiniTableField* field, + double default_val); + +UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, + const upb_MiniTableField* f, + float default_val); + +UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, + const upb_MiniTableField* f, + int32_t default_val); + +UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg, + const upb_MiniTableField* f, + int64_t default_val); + +UPB_API_INLINE const upb_Map* upb_Message_GetMap(const upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE const upb_Message* upb_Message_GetMessage( + const upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE upb_Array* upb_Message_GetMutableArray( + upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE upb_Map* upb_Message_GetMutableMap(upb_Message* msg, + const upb_MiniTableField* f); + +UPB_API_INLINE upb_Message* upb_Message_GetMutableMessage( + upb_Message* msg, const upb_MiniTableField* f); + +UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( + upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena); + +UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap( + upb_Message* msg, const upb_MiniTable* map_entry_mini_table, + const upb_MiniTableField* f, upb_Arena* arena); + +UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( + upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena); + +UPB_API_INLINE upb_StringView +upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field, + upb_StringView default_val); + +UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, + const upb_MiniTableField* f, + uint32_t default_val); + +UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, + const upb_MiniTableField* f, + uint64_t default_val); + +UPB_API_INLINE void upb_Message_SetClosedEnum(upb_Message* msg, + const upb_MiniTableField* f, + int32_t value); + +// BaseField Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE void upb_Message_SetBaseField(upb_Message* msg, + const upb_MiniTableField* f, + const void* val); + +UPB_API_INLINE void upb_Message_SetBaseFieldBool(struct upb_Message* msg, + const upb_MiniTableField* f, + bool value); + +UPB_API_INLINE void upb_Message_SetBaseFieldDouble(struct upb_Message* msg, + const upb_MiniTableField* f, + double value); + +UPB_API_INLINE void upb_Message_SetBaseFieldFloat(struct upb_Message* msg, + const upb_MiniTableField* f, + float value); + +UPB_API_INLINE void upb_Message_SetBaseFieldInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + int32_t value); + +UPB_API_INLINE void upb_Message_SetBaseFieldInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + int64_t value); + +UPB_API_INLINE void upb_Message_SetBaseFieldMessage(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_Message* value); + +UPB_API_INLINE void upb_Message_SetBaseFieldString(struct upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value); + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt32(struct upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value); + +UPB_API_INLINE void upb_Message_SetBaseFieldUInt64(struct upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value); + +// Extension Getters /////////////////////////////////////////////////////////// +UPB_API_INLINE bool upb_Message_GetExtensionBool( + const upb_Message* msg, const upb_MiniTableExtension* f, bool default_val); + +UPB_API_INLINE double upb_Message_GetExtensionDouble( + const upb_Message* msg, const upb_MiniTableExtension* f, + double default_val); + +UPB_API_INLINE float upb_Message_GetExtensionFloat( + const upb_Message* msg, const upb_MiniTableExtension* f, float default_val); + +UPB_API_INLINE int32_t upb_Message_GetExtensionInt32( + const upb_Message* msg, const upb_MiniTableExtension* f, + int32_t default_val); + +UPB_API_INLINE int64_t upb_Message_GetExtensionInt64( + const upb_Message* msg, const upb_MiniTableExtension* f, + int64_t default_val); + +UPB_API_INLINE uint32_t upb_Message_GetExtensionUInt32( + const upb_Message* msg, const upb_MiniTableExtension* f, + uint32_t default_val); + +UPB_API_INLINE uint64_t upb_Message_GetExtensionUInt64( + const upb_Message* msg, const upb_MiniTableExtension* f, + uint64_t default_val); + +UPB_API_INLINE upb_StringView upb_Message_GetExtensionString( + const upb_Message* msg, const upb_MiniTableExtension* f, + upb_StringView default_val); + +UPB_API_INLINE upb_Message* upb_Message_GetExtensionMessage( + const upb_Message* msg, const upb_MiniTableExtension* f, + struct upb_Message* default_val); + +UPB_API_INLINE const upb_Array* upb_Message_GetExtensionArray( + const upb_Message* msg, const upb_MiniTableExtension* f); + +UPB_API_INLINE upb_Array* upb_Message_GetExtensionMutableArray( + upb_Message* msg, const upb_MiniTableExtension* f); + +// Extension Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetExtension(upb_Message* msg, + const upb_MiniTableExtension* e, + const void* value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionMessage( + struct upb_Message* msg, const upb_MiniTableExtension* e, + struct upb_Message* value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionBool( + struct upb_Message* msg, const upb_MiniTableExtension* e, bool value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionDouble( + struct upb_Message* msg, const upb_MiniTableExtension* e, double value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionFloat( + struct upb_Message* msg, const upb_MiniTableExtension* e, float value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, int32_t value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, int64_t value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionString( + struct upb_Message* msg, const upb_MiniTableExtension* e, + upb_StringView value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionUInt32( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint32_t value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetExtensionUInt64( + struct upb_Message* msg, const upb_MiniTableExtension* e, uint64_t value, + upb_Arena* a); + +// Universal Setters /////////////////////////////////////////////////////////// + +UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, + const upb_MiniTableField* f, bool value, + upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, + const upb_MiniTableField* f, + double value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, + const upb_MiniTableField* f, + float value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, + const upb_MiniTableField* f, + int32_t value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, + const upb_MiniTableField* f, + int64_t value, upb_Arena* a); + +// Unlike the other similarly-named setters, this function can only be +// called on base fields. Prefer upb_Message_SetBaseFieldMessage(). +UPB_API_INLINE void upb_Message_SetMessage(upb_Message* msg, + const upb_MiniTableField* f, + upb_Message* value); + +UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, + const upb_MiniTableField* f, + upb_StringView value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, + const upb_MiniTableField* f, + uint32_t value, upb_Arena* a); + +UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, + const upb_MiniTableField* f, + uint64_t value, upb_Arena* a); + +//////////////////////////////////////////////////////////////////////////////// + +UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( + upb_Message* msg, const upb_MiniTableField* f, size_t size, + upb_Arena* arena); + +UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( + const upb_Message* message, const upb_MiniTableField* oneof_field); + +// For a field `f` which is in a oneof, return the field of that +// oneof that is actually set (or NULL if none). +UPB_API_INLINE const upb_MiniTableField* upb_Message_WhichOneof( + const upb_Message* msg, const upb_MiniTable* m, + const upb_MiniTableField* f); + +// Updates a map entry given an entry message. +bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* field, + upb_Message* map_entry_message, upb_Arena* arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#if defined(__cplusplus) +// Temporary overloads for functions whose signature has recently changed. +UPB_DEPRECATE_AND_INLINE() +inline upb_Message* upb_Message_GetOrCreateMutableMessage( + upb_Message* msg, const upb_MiniTable* mini_table, + const upb_MiniTableField* f, upb_Arena* arena) { + return upb_Message_GetOrCreateMutableMessage(msg, f, arena); +} + +UPB_DEPRECATE_AND_INLINE() +inline void upb_Message_SetClosedEnum(upb_Message* msg, + const upb_MiniTable* msg_mini_table, + const upb_MiniTableField* f, + int32_t value) { + upb_Message_SetClosedEnum(msg, f, value); +} + +UPB_DEPRECATE_AND_INLINE() +inline bool upb_Message_SetMapEntry(upb_Map* map, + const upb_MiniTable* mini_table, + const upb_MiniTableField* field, + upb_Message* map_entry_message, + upb_Arena* arena) { + return upb_Message_SetMapEntry(map, field, map_entry_message, arena); +} +#endif + + +#endif // UPB_MESSAGE_ACCESSORS_H_ + +// These functions are only used by generated code. + +#ifndef UPB_MESSAGE_MAP_GENCODE_UTIL_H_ +#define UPB_MESSAGE_MAP_GENCODE_UTIL_H_ + +// This header file is referenced by multiple files. Leave it empty. +// TODO: b/399481227 - Remove this header file, after all the references are +// cleaned up. +#endif /* UPB_MESSAGE_MAP_GENCODE_UTIL_H_ */ + +#ifndef UPB_MINI_TABLE_DECODE_H_ +#define UPB_MINI_TABLE_DECODE_H_ + +#include <stddef.h> + + +#ifndef UPB_BASE_STATUS_H_ +#define UPB_BASE_STATUS_H_ + +#include <stdarg.h> + +// Must be last. + +#define _kUpb_Status_MaxMessage 511 + +typedef struct { + bool ok; + char msg[_kUpb_Status_MaxMessage]; // Error message; NULL-terminated. +} upb_Status; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const char* upb_Status_ErrorMessage(const upb_Status* status); +UPB_API bool upb_Status_IsOk(const upb_Status* status); + +// These are no-op if |status| is NULL. +UPB_API void upb_Status_Clear(upb_Status* status); +void upb_Status_SetErrorMessage(upb_Status* status, const char* msg); +void upb_Status_SetErrorFormat(upb_Status* status, const char* fmt, ...) + UPB_PRINTF(2, 3); +void upb_Status_VSetErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); +void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, + va_list args) UPB_PRINTF(2, 0); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_STATUS_H_ */ + +#ifndef UPB_MINI_TABLE_SUB_H_ +#define UPB_MINI_TABLE_SUB_H_ + + +// Must be last. + +typedef union upb_MiniTableSub upb_MiniTableSub; + +#ifdef __cplusplus +extern "C" { +#endif + +// Constructors + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromEnum(const upb_MiniTableEnum* subenum); + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromMessage(const upb_MiniTable* submsg); + +// Getters + +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTableSub_Enum( + upb_MiniTableSub sub); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableSub_Message( + upb_MiniTableSub sub); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_SUB_H_ */ + +// Export the newer headers, for legacy users. New users should include the +// more specific headers directly. +// IWYU pragma: begin_exports + +#ifndef UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ +#define UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Builds a upb_MiniTableEnum from an enum mini descriptor. +// The mini descriptor must be for an enum, not a message. +UPB_API upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len, + upb_Arena* arena, + upb_Status* status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_DESCRIPTOR_BUILD_ENUM_H_ + +// Functions for linking MiniTables together once they are built from a +// MiniDescriptor. +// +// These functions have names like upb_MiniTable_Link() because they operate on +// MiniTables. We put them here, rather than in the mini_table/ directory, +// because they are only needed when building MiniTables from MiniDescriptors. +// The interfaces in mini_table/ assume that MiniTables are immutable. + +#ifndef UPB_MINI_DESCRIPTOR_LINK_H_ +#define UPB_MINI_DESCRIPTOR_LINK_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Links a sub-message field to a MiniTable for that sub-message. If a +// sub-message field is not linked, it will be treated as an unknown field +// during parsing, and setting the field will not be allowed. It is possible +// to link the message field later, at which point it will no longer be treated +// as unknown. However there is no synchronization for this operation, which +// means parallel mutation requires external synchronization. +// Returns success/failure. +UPB_API bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, + upb_MiniTableField* field, + const upb_MiniTable* sub); + +// Links an enum field to a MiniTable for that enum. +// All enum fields must be linked prior to parsing. +// Returns success/failure. +UPB_API bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, + upb_MiniTableField* field, + const upb_MiniTableEnum* sub); + +// Returns a list of fields that require linking at runtime, to connect the +// MiniTable to its sub-messages and sub-enums. The list of fields will be +// written to the `subs` array, which must have been allocated by the caller +// and must be large enough to hold a list of all fields in the message. +// +// The order of the fields returned by this function is significant: it matches +// the order expected by upb_MiniTable_Link() below. +// +// The return value packs the sub-message count and sub-enum count into a single +// integer like so: +// return (msg_count << 16) | enum_count; +UPB_API uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, + const upb_MiniTableField** subs); + +// Links a message to its sub-messages and sub-enums. The caller must pass +// arrays of sub-tables and sub-enums, in the same length and order as is +// returned by upb_MiniTable_GetSubList() above. However, individual elements +// of the sub_tables may be NULL if those sub-messages were tree shaken. +// +// Returns false if either array is too short, or if any of the tables fails +// to link. +UPB_API bool upb_MiniTable_Link(upb_MiniTable* mt, + const upb_MiniTable** sub_tables, + size_t sub_table_count, + const upb_MiniTableEnum** sub_enums, + size_t sub_enum_count); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_DESCRIPTOR_LINK_H_ +// IWYU pragma: end_exports + +// Must be last. + +typedef enum { + kUpb_MiniTablePlatform_32Bit, + kUpb_MiniTablePlatform_64Bit, + kUpb_MiniTablePlatform_Native = + UPB_SIZE(kUpb_MiniTablePlatform_32Bit, kUpb_MiniTablePlatform_64Bit), +} upb_MiniTablePlatform; + +#ifdef __cplusplus +extern "C" { +#endif + +// Builds a mini table from the data encoded in the buffer [data, len]. If any +// errors occur, returns NULL and sets a status message. In the success case, +// the caller must call upb_MiniTable_SetSub*() for all message or proto2 enum +// fields to link the table to the appropriate sub-tables. +upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, upb_Status* status); + +UPB_API_INLINE upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len, + upb_Arena* arena, + upb_Status* status) { + return _upb_MiniTable_Build(data, len, kUpb_MiniTablePlatform_Native, arena, + status); +} + +// Initializes a MiniTableExtension buffer that has already been allocated. +// This is needed by upb_FileDef and upb_MessageDef, which allocate all of the +// extensions together in a single contiguous array. +const char* _upb_MiniTableExtension_Init(const char* data, size_t len, + upb_MiniTableExtension* ext, + const upb_MiniTable* extendee, + upb_MiniTableSub sub, + upb_MiniTablePlatform platform, + upb_Status* status); + +UPB_API_INLINE const char* upb_MiniTableExtension_Init( + const char* data, size_t len, upb_MiniTableExtension* ext, + const upb_MiniTable* extendee, upb_MiniTableSub sub, upb_Status* status) { + return _upb_MiniTableExtension_Init(data, len, ext, extendee, sub, + kUpb_MiniTablePlatform_Native, status); +} + +UPB_API upb_MiniTableExtension* _upb_MiniTableExtension_Build( + const char* data, size_t len, const upb_MiniTable* extendee, + upb_MiniTableSub sub, upb_MiniTablePlatform platform, upb_Arena* arena, + upb_Status* status); + +UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( + const char* data, size_t len, const upb_MiniTable* extendee, + upb_Arena* arena, upb_Status* status) { + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(NULL); + return _upb_MiniTableExtension_Build( + data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); +} + +UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( + const char* data, size_t len, const upb_MiniTable* extendee, + const upb_MiniTable* submsg, upb_Arena* arena, upb_Status* status) { + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(submsg); + return _upb_MiniTableExtension_Build( + data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); +} + +UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildEnum( + const char* data, size_t len, const upb_MiniTable* extendee, + const upb_MiniTableEnum* subenum, upb_Arena* arena, upb_Status* status) { + upb_MiniTableSub sub = upb_MiniTableSub_FromEnum(subenum); + return _upb_MiniTableExtension_Build( + data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); +} + +// Like upb_MiniTable_Build(), but the user provides a buffer of layout data so +// it can be reused from call to call, avoiding repeated +// upb_grealloc()/upb_gfree(). +// +// The caller owns `*buf` both before and after the call, and must upb_gfree() +// it when it is no longer in use. The function will upb_grealloc() `*buf` as +// necessary, updating `*size` accordingly. +upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, + upb_MiniTablePlatform platform, + upb_Arena* arena, void** buf, + size_t* buf_size, upb_Status* status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_DECODE_H_ */ + +#ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ +#define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Extension registry: a dynamic data structure that stores a map of: + * (upb_MiniTable, number) -> extension info + * + * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing + * binary format. + * + * upb_ExtensionRegistry is part of the mini-table (msglayout) family of + * objects. Like all mini-table objects, it is suitable for reflection-less + * builds that do not want to expose names into the binary. + * + * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory + * allocation and dynamic initialization: + * * If reflection is being used, then upb_DefPool will construct an appropriate + * upb_ExtensionRegistry automatically. + * * For a mini-table only build, the user must manually construct the + * upb_ExtensionRegistry and populate it with all of the extensions the user + * cares about. + * * A third alternative is to manually unpack relevant extensions after the + * main parse is complete, similar to how Any works. This is perhaps the + * nicest solution from the perspective of reducing dependencies, avoiding + * dynamic memory allocation, and avoiding the need to parse uninteresting + * extensions. The downsides are: + * (1) parse errors are not caught during the main parse + * (2) the CPU hit of parsing comes during access, which could cause an + * undesirable stutter in application performance. + * + * Users cannot directly get or put into this map. Users can only add the + * extensions from a generated module and pass the extension registry to the + * binary decoder. + * + * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use + * reflection do not need to populate a upb_ExtensionRegistry directly. + */ + +typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; + +// LINT.IfChange +typedef enum { + kUpb_ExtensionRegistryStatus_Ok = 0, + kUpb_ExtensionRegistryStatus_DuplicateEntry = 1, + kUpb_ExtensionRegistryStatus_OutOfMemory = 2, + kUpb_ExtensionRegistryStatus_InvalidExtension = 3, +} upb_ExtensionRegistryStatus; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/mini_table/extension_registry.rs) + +// Creates a upb_ExtensionRegistry in the given arena. +// The arena must outlive any use of the extreg. +UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); + +UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add( + upb_ExtensionRegistry* r, const upb_MiniTableExtension* e); + +// Adds the given extension info for the array |e| of size |count| into the +// registry. If there are any errors, the entire array is backed out. +// The extensions must outlive the registry. +// Possible errors include OOM or an extension number that already exists. +upb_ExtensionRegistryStatus upb_ExtensionRegistry_AddArray( + upb_ExtensionRegistry* r, const upb_MiniTableExtension** e, size_t count); + +// Looks up the extension (if any) defined for message type |t| and field +// number |num|. Returns the extension if found, otherwise NULL. +UPB_API const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( + const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num); + +// Returns the number of extensions in the registry. For testing/debugging only. +UPB_API size_t upb_ExtensionRegistry_Size(const upb_ExtensionRegistry* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ */ + +#ifndef UPB_MINI_TABLE_FILE_H_ +#define UPB_MINI_TABLE_FILE_H_ + + +#ifndef UPB_MINI_TABLE_INTERNAL_FILE_H_ +#define UPB_MINI_TABLE_INTERNAL_FILE_H_ + +// Must be last. + +struct upb_MiniTableFile { + const struct upb_MiniTable** UPB_PRIVATE(msgs); + const struct upb_MiniTableEnum** UPB_PRIVATE(enums); + const struct upb_MiniTableExtension** UPB_PRIVATE(exts); + int UPB_PRIVATE(msg_count); + int UPB_PRIVATE(enum_count); + int UPB_PRIVATE(ext_count); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE int upb_MiniTableFile_EnumCount( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(enum_count); +} + +UPB_API_INLINE int upb_MiniTableFile_ExtensionCount( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(ext_count); +} + +UPB_API_INLINE int upb_MiniTableFile_MessageCount( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(msg_count); +} + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableFile_Enum( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(enum_count)); + return f->UPB_PRIVATE(enums)[i]; +} + +UPB_API_INLINE const struct upb_MiniTableExtension* upb_MiniTableFile_Extension( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(ext_count)); + return f->UPB_PRIVATE(exts)[i]; +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableFile_Message( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(msg_count)); + return f->UPB_PRIVATE(msgs)[i]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_FILE_H_ */ + +// Must be last. + +typedef struct upb_MiniTableFile upb_MiniTableFile; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTableFile_Enum( + const upb_MiniTableFile* f, int i); + +UPB_API_INLINE int upb_MiniTableFile_EnumCount(const upb_MiniTableFile* f); + +UPB_API_INLINE const upb_MiniTableExtension* upb_MiniTableFile_Extension( + const upb_MiniTableFile* f, int i); + +UPB_API_INLINE int upb_MiniTableFile_ExtensionCount(const upb_MiniTableFile* f); + +UPB_API_INLINE const upb_MiniTable* upb_MiniTableFile_Message( + const upb_MiniTableFile* f, int i); + +UPB_API_INLINE int upb_MiniTableFile_MessageCount(const upb_MiniTableFile* f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_FILE_H_ */ + +#ifndef UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ +#define UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct UPB_PRIVATE(upb_GeneratedExtensionListEntry) { + const struct upb_MiniTableExtension** start; + const struct upb_MiniTableExtension** stop; + const struct UPB_PRIVATE(upb_GeneratedExtensionListEntry) * next; +} UPB_PRIVATE(upb_GeneratedExtensionListEntry); + +struct upb_GeneratedRegistryRef { + struct upb_Arena* UPB_PRIVATE(arena); + const struct upb_ExtensionRegistry* UPB_PRIVATE(registry); +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ */ + +// upb_decode: parsing into a upb_Message using a upb_MiniTable. + +#ifndef UPB_WIRE_DECODE_H_ +#define UPB_WIRE_DECODE_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// LINT.IfChange +enum { + /* If set, strings and unknown fields will alias the input buffer instead of + * copying into the arena. */ + kUpb_DecodeOption_AliasString = 1, + + /* If set, the parse will return failure if any message is missing any + * required fields when the message data ends. The parse will still continue, + * and the failure will only be reported at the end. + * + * IMPORTANT CAVEATS: + * + * 1. This can throw a false positive failure if an incomplete message is seen + * on the wire but is later completed when the sub-message occurs again. + * For this reason, a second pass is required to verify a failure, to be + * truly robust. + * + * 2. This can return a false success if you are decoding into a message that + * already has some sub-message fields present. If the sub-message does + * not occur in the binary payload, we will never visit it and discover the + * incomplete sub-message. For this reason, this check is only useful for + * implementing ParseFromString() semantics. For MergeFromString(), a + * post-parse validation step will always be necessary. */ + kUpb_DecodeOption_CheckRequired = 2, + + /* EXPERIMENTAL: + * + * If set, decoding will enforce UTF-8 validation for string fields, even for + * proto2 or fields with `features.utf8_validation = NONE`. Normally, only + * proto3 string fields will be validated for UTF-8. Decoding will return + * kUpb_DecodeStatus_BadUtf8 for non-UTF-8 strings, which is the same behavior + * as non-UTF-8 proto3 string fields. + */ + kUpb_DecodeOption_AlwaysValidateUtf8 = 8, + + /* EXPERIMENTAL: + * + * If set, the fasttable decoder will not be used. */ + kUpb_DecodeOption_DisableFastTable = 16, +}; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/wire.rs:decode_status) + +UPB_INLINE uint32_t upb_DecodeOptions_MaxDepth(uint16_t depth) { + return (uint32_t)depth << 16; +} + +uint16_t upb_DecodeOptions_GetEffectiveMaxDepth(uint32_t options); + +// Enforce an upper bound on recursion depth. +UPB_INLINE int upb_Decode_LimitDepth(uint32_t decode_options, uint32_t limit) { + uint32_t max_depth = upb_DecodeOptions_GetEffectiveMaxDepth(decode_options); + if (max_depth > limit) max_depth = limit; + return (int)(upb_DecodeOptions_MaxDepth(max_depth) | + (decode_options & 0xffff)); +} + +// LINT.IfChange +typedef enum { + kUpb_DecodeStatus_Ok = 0, + kUpb_DecodeStatus_OutOfMemory = 1, // Arena alloc failed + kUpb_DecodeStatus_Malformed = 2, // Wire format was corrupt + kUpb_DecodeStatus_BadUtf8 = 3, // String field had bad UTF-8 + kUpb_DecodeStatus_MaxDepthExceeded = + 4, // Exceeded upb_DecodeOptions_MaxDepth + + // kUpb_DecodeOption_CheckRequired failed (see above), but the parse otherwise + // succeeded. + kUpb_DecodeStatus_MissingRequired = 5, +} upb_DecodeStatus; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/wire/wire.rs:decode_status) + +UPB_API upb_DecodeStatus upb_Decode(const char* buf, size_t size, + upb_Message* msg, const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena); + +// Same as upb_Decode but with a varint-encoded length prepended. +// On success 'num_bytes_read' will be set to the how many bytes were read, +// on failure the contents of num_bytes_read is undefined. +UPB_API upb_DecodeStatus upb_DecodeLengthPrefixed( + const char* buf, size_t size, upb_Message* msg, size_t* num_bytes_read, + const upb_MiniTable* mt, const upb_ExtensionRegistry* extreg, int options, + upb_Arena* arena); + +// For testing: decode with tracing. +UPB_API upb_DecodeStatus upb_DecodeWithTrace( + const char* buf, size_t size, upb_Message* msg, const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, int options, upb_Arena* arena, + char* trace_buf, size_t trace_size); + +// Utility function for wrapper languages to get an error string from a +// upb_DecodeStatus. +UPB_API const char* upb_DecodeStatus_String(upb_DecodeStatus status); +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_DECODE_H_ */ + +// upb_Encode: parsing from a upb_Message using a upb_MiniTable. + +#ifndef UPB_WIRE_ENCODE_H_ +#define UPB_WIRE_ENCODE_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + /* If set, the results of serializing will be deterministic across all + * instances of this binary. There are no guarantees across different + * binary builds. + * + * If your proto contains maps, the encoder will need to malloc()/free() + * memory during encode. */ + kUpb_EncodeOption_Deterministic = 1, + + // When set, unknown fields are not encoded. + kUpb_EncodeOption_SkipUnknown = 2, + + // When set, the encode will fail if any required fields are missing. + kUpb_EncodeOption_CheckRequired = 4, +}; + +// LINT.IfChange +typedef enum { + kUpb_EncodeStatus_Ok = 0, + kUpb_EncodeStatus_OutOfMemory = 1, // Arena alloc failed + kUpb_EncodeStatus_MaxDepthExceeded = 2, + + // One or more required fields are missing. Only returned if + // kUpb_EncodeOption_CheckRequired is set. + kUpb_EncodeStatus_MissingRequired = 3, + + // The message is larger than protobuf's 2GB size limit. + kUpb_EncodeStatus_MaxSizeExceeded = 4, +} upb_EncodeStatus; +// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/wire/wire.rs:encode_status) + +UPB_INLINE uint32_t upb_EncodeOptions_MaxDepth(uint16_t depth) { + return (uint32_t)depth << 16; +} + +uint16_t upb_EncodeOptions_GetEffectiveMaxDepth(uint32_t options); + +// Enforce an upper bound on recursion depth. +UPB_INLINE int upb_Encode_LimitDepth(uint32_t encode_options, uint32_t limit) { + uint32_t max_depth = upb_EncodeOptions_GetEffectiveMaxDepth(encode_options); + if (max_depth > limit) max_depth = limit; + return (int)(upb_EncodeOptions_MaxDepth(max_depth) | + (encode_options & 0xffff)); +} + +UPB_API upb_EncodeStatus upb_Encode(const upb_Message* msg, + const upb_MiniTable* l, int options, + upb_Arena* arena, char** buf, size_t* size); + +// Encodes the message prepended by a varint of the serialized length. +UPB_API upb_EncodeStatus upb_EncodeLengthPrefixed(const upb_Message* msg, + const upb_MiniTable* l, + int options, upb_Arena* arena, + char** buf, size_t* size); +// Utility function for wrapper languages to get an error string from a +// upb_EncodeStatus. +UPB_API const char* upb_EncodeStatus_String(upb_EncodeStatus status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_ENCODE_H_ */ +#ifdef UPB_INCLUDE_FAST_DECODE +#endif +// IWYU pragma: end_exports + +#undef UPB_INCLUDE_FAST_DECODE + +#endif // UPB_GENERATED_CODE_SUPPORT_H_ +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init; +extern const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__DescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__DescriptorProto__ExtensionRange_msg_init; +extern const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init; +extern const upb_MiniTable google__protobuf__ExtensionRangeOptions_msg_init; +extern const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_init; +extern const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__EnumDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init; +extern const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init; +extern const upb_MiniTable google__protobuf__FileOptions_msg_init; +extern const upb_MiniTable google__protobuf__MessageOptions_msg_init; +extern const upb_MiniTable google__protobuf__FieldOptions_msg_init; +extern const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init; +extern const upb_MiniTable google__protobuf__FieldOptions__FeatureSupport_msg_init; +extern const upb_MiniTable google__protobuf__OneofOptions_msg_init; +extern const upb_MiniTable google__protobuf__EnumOptions_msg_init; +extern const upb_MiniTable google__protobuf__EnumValueOptions_msg_init; +extern const upb_MiniTable google__protobuf__ServiceOptions_msg_init; +extern const upb_MiniTable google__protobuf__MethodOptions_msg_init; +extern const upb_MiniTable google__protobuf__UninterpretedOption_msg_init; +extern const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSet_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSet__VisibilityFeature_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init; +extern const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init; +extern const upb_MiniTable google__protobuf__SourceCodeInfo_msg_init; +extern const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init; +extern const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init; +extern const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init; + +extern const upb_MiniTableEnum google__protobuf__Edition_enum_init; +extern const upb_MiniTableEnum google__protobuf__ExtensionRangeOptions__VerificationState_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__EnforceNamingStyle_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__EnumType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__FieldPresence_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__JsonFormat_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__MessageEncoding_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__RepeatedFieldEncoding_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__Utf8Validation_enum_init; +extern const upb_MiniTableEnum google__protobuf__FeatureSet__VisibilityFeature__DefaultSymbolVisibility_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Label_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldDescriptorProto__Type_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__CType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__JSType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__OptionRetention_enum_init; +extern const upb_MiniTableEnum google__protobuf__FieldOptions__OptionTargetType_enum_init; +extern const upb_MiniTableEnum google__protobuf__FileOptions__OptimizeMode_enum_init; +extern const upb_MiniTableEnum google__protobuf__GeneratedCodeInfo__Annotation__Semantic_enum_init; +extern const upb_MiniTableEnum google__protobuf__MethodOptions__IdempotencyLevel_enum_init; +extern const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init; +extern const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ */ + +#ifndef UPB_BASE_INTERNAL_LOG2_H_ +#define UPB_BASE_INTERNAL_LOG2_H_ + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE int upb_Log2Ceiling(size_t x) { + if (x <= 1) return 0; +#if SIZE_MAX == ULLONG_MAX && UPB_HAS_BUILTIN(__builtin_clzll) + return (sizeof(size_t) * CHAR_BIT) - __builtin_clzll(x - 1); +#elif SIZE_MAX == ULONG_MAX && UPB_HAS_BUILTIN(__builtin_clzl) + return (sizeof(size_t) * CHAR_BIT) - __builtin_clzl(x - 1); +#elif SIZE_MAX == UINT_MAX && UPB_HAS_BUILTIN(__builtin_clz) + return (sizeof(size_t) * CHAR_BIT) - __builtin_clz(x - 1); +#else + if (x > SIZE_MAX / 2) return sizeof(size_t) * CHAR_BIT; + int lg2 = 0; + while ((1 << lg2) < x) lg2++; + return lg2; +#endif +} + +// Returns the smallest power of two that is greater than or equal to x. Returns +// SIZE_MAX if the computation would overflow. +UPB_INLINE size_t upb_RoundUpToPowerOfTwo(size_t x) { + int lg2 = upb_Log2Ceiling(x); + UPB_ASSERT(lg2 >= 0 && lg2 <= (int)sizeof(size_t) * CHAR_BIT); + if (lg2 == sizeof(size_t) * CHAR_BIT) { + return SIZE_MAX; + } + return ((size_t)1) << lg2; +} + +UPB_INLINE bool upb_ShlOverflow(size_t* a, unsigned int b) { + if (*a > (SIZE_MAX >> b)) { + return true; + } + *a <<= b; + return false; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_BASE_INTERNAL_LOG2_H_ */ + +#ifndef UPB_HASH_EXT_TABLE_H_ +#define UPB_HASH_EXT_TABLE_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +typedef struct { + upb_table t; +} upb_exttable; + +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize a table. If memory allocation failed, false is returned and +// the table is uninitialized. +bool upb_exttable_init(upb_exttable* table, size_t expected_size, upb_Arena* a); + +// Returns the number of values in the table. +UPB_INLINE size_t upb_exttable_count(const upb_exttable* t) { + return t->t.count; +} + +void upb_exttable_clear(upb_exttable* t); + +// Inserts the given key and value into the hashtable. +// The key must not already exist in the hash table, and must not be NULL. +// +// If a table resize was required but memory allocation failed, false is +// returned and the table is unchanged. +bool upb_exttable_insert(upb_exttable* t, const void* k, const uint32_t* v, + upb_Arena* a); + +// Looks up key and ext_number in this table, returning the value if the key was +// found, or NULL otherwise. +const uint32_t* upb_exttable_lookup(const upb_exttable* t, const void* k, + uint32_t ext_number); + +// Removes an item from the table. Returns the removed item if the remove was +// successful, or NULL if the key was not found. +const uint32_t* upb_exttable_remove(upb_exttable* t, const void* k, + uint32_t ext_number); + +size_t upb_exttable_size(const upb_exttable* t); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_HASH_EXT_TABLE_H_ */ + +#ifndef UPB_JSON_DECODE_H_ +#define UPB_JSON_DECODE_H_ + +#include <stddef.h> + + +#ifndef UPB_REFLECTION_DEF_H_ +#define UPB_REFLECTION_DEF_H_ + +// IWYU pragma: begin_exports + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_DEF_POOL_H_ +#define UPB_REFLECTION_DEF_POOL_H_ + + +// IWYU pragma: private, include "upb/reflection/def.h" + +// Declarations common to all public def types. + +#ifndef UPB_REFLECTION_COMMON_H_ +#define UPB_REFLECTION_COMMON_H_ + +#ifndef GOOGLE_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H__ +#define GOOGLE_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H__ + +// IWYU pragma: begin_exports + +#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +// This header is checked in. +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1 +// This header is generated at build time by the bootstrapping process. +#else +// This is the normal header, generated by upb_c_proto_library(). +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/descriptor.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_H_ +#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct google_protobuf_FileDescriptorSet { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FileDescriptorSet; + +typedef struct google_protobuf_FileDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FileDescriptorProto; + +typedef struct google_protobuf_DescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_DescriptorProto; + +typedef struct google_protobuf_DescriptorProto_ExtensionRange { + upb_Message UPB_PRIVATE(base); +} google_protobuf_DescriptorProto_ExtensionRange; + +typedef struct google_protobuf_DescriptorProto_ReservedRange { + upb_Message UPB_PRIVATE(base); +} google_protobuf_DescriptorProto_ReservedRange; + +typedef struct google_protobuf_ExtensionRangeOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ExtensionRangeOptions; + +typedef struct google_protobuf_ExtensionRangeOptions_Declaration { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ExtensionRangeOptions_Declaration; + +typedef struct google_protobuf_FieldDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldDescriptorProto; + +typedef struct google_protobuf_OneofDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_OneofDescriptorProto; + +typedef struct google_protobuf_EnumDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumDescriptorProto; + +typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumDescriptorProto_EnumReservedRange; + +typedef struct google_protobuf_EnumValueDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumValueDescriptorProto; + +typedef struct google_protobuf_ServiceDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ServiceDescriptorProto; + +typedef struct google_protobuf_MethodDescriptorProto { + upb_Message UPB_PRIVATE(base); +} google_protobuf_MethodDescriptorProto; + +typedef struct google_protobuf_FileOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FileOptions; + +typedef struct google_protobuf_MessageOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_MessageOptions; + +typedef struct google_protobuf_FieldOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldOptions; + +typedef struct google_protobuf_FieldOptions_EditionDefault { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldOptions_EditionDefault; + +typedef struct google_protobuf_FieldOptions_FeatureSupport { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FieldOptions_FeatureSupport; + +typedef struct google_protobuf_OneofOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_OneofOptions; + +typedef struct google_protobuf_EnumOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumOptions; + +typedef struct google_protobuf_EnumValueOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_EnumValueOptions; + +typedef struct google_protobuf_ServiceOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_ServiceOptions; + +typedef struct google_protobuf_MethodOptions { + upb_Message UPB_PRIVATE(base); +} google_protobuf_MethodOptions; + +typedef struct google_protobuf_UninterpretedOption { + upb_Message UPB_PRIVATE(base); +} google_protobuf_UninterpretedOption; + +typedef struct google_protobuf_UninterpretedOption_NamePart { + upb_Message UPB_PRIVATE(base); +} google_protobuf_UninterpretedOption_NamePart; + +typedef struct google_protobuf_FeatureSet { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSet; + +typedef struct google_protobuf_FeatureSet_VisibilityFeature { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSet_VisibilityFeature; + +typedef struct google_protobuf_FeatureSetDefaults { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSetDefaults; + +typedef struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault { + upb_Message UPB_PRIVATE(base); +} google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault; + +typedef struct google_protobuf_SourceCodeInfo { + upb_Message UPB_PRIVATE(base); +} google_protobuf_SourceCodeInfo; + +typedef struct google_protobuf_SourceCodeInfo_Location { + upb_Message UPB_PRIVATE(base); +} google_protobuf_SourceCodeInfo_Location; + +typedef struct google_protobuf_GeneratedCodeInfo { + upb_Message UPB_PRIVATE(base); +} google_protobuf_GeneratedCodeInfo; + +typedef struct google_protobuf_GeneratedCodeInfo_Annotation { + upb_Message UPB_PRIVATE(base); +} google_protobuf_GeneratedCodeInfo_Annotation; + + +typedef enum { + google_protobuf_EDITION_UNKNOWN = 0, + google_protobuf_EDITION_1_TEST_ONLY = 1, + google_protobuf_EDITION_2_TEST_ONLY = 2, + google_protobuf_EDITION_LEGACY = 900, + google_protobuf_EDITION_PROTO2 = 998, + google_protobuf_EDITION_PROTO3 = 999, + google_protobuf_EDITION_2023 = 1000, + google_protobuf_EDITION_2024 = 1001, + google_protobuf_EDITION_2026 = 1002, + google_protobuf_EDITION_UNSTABLE = 9999, + google_protobuf_EDITION_99997_TEST_ONLY = 99997, + google_protobuf_EDITION_99998_TEST_ONLY = 99998, + google_protobuf_EDITION_99999_TEST_ONLY = 99999, + google_protobuf_EDITION_MAX = 2147483647 +} google_protobuf_Edition; + +typedef enum { + google_protobuf_ExtensionRangeOptions_DECLARATION = 0, + google_protobuf_ExtensionRangeOptions_UNVERIFIED = 1 +} google_protobuf_ExtensionRangeOptions_VerificationState; + +typedef enum { + google_protobuf_FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN = 0, + google_protobuf_FeatureSet_STYLE2024 = 1, + google_protobuf_FeatureSet_STYLE_LEGACY = 2, + google_protobuf_FeatureSet_STYLE2026 = 3 +} google_protobuf_FeatureSet_EnforceNamingStyle; + +typedef enum { + google_protobuf_FeatureSet_ENUM_TYPE_UNKNOWN = 0, + google_protobuf_FeatureSet_OPEN = 1, + google_protobuf_FeatureSet_CLOSED = 2 +} google_protobuf_FeatureSet_EnumType; + +typedef enum { + google_protobuf_FeatureSet_FIELD_PRESENCE_UNKNOWN = 0, + google_protobuf_FeatureSet_EXPLICIT = 1, + google_protobuf_FeatureSet_IMPLICIT = 2, + google_protobuf_FeatureSet_LEGACY_REQUIRED = 3 +} google_protobuf_FeatureSet_FieldPresence; + +typedef enum { + google_protobuf_FeatureSet_JSON_FORMAT_UNKNOWN = 0, + google_protobuf_FeatureSet_ALLOW = 1, + google_protobuf_FeatureSet_LEGACY_BEST_EFFORT = 2 +} google_protobuf_FeatureSet_JsonFormat; + +typedef enum { + google_protobuf_FeatureSet_MESSAGE_ENCODING_UNKNOWN = 0, + google_protobuf_FeatureSet_LENGTH_PREFIXED = 1, + google_protobuf_FeatureSet_DELIMITED = 2 +} google_protobuf_FeatureSet_MessageEncoding; + +typedef enum { + google_protobuf_FeatureSet_REPEATED_FIELD_ENCODING_UNKNOWN = 0, + google_protobuf_FeatureSet_PACKED = 1, + google_protobuf_FeatureSet_EXPANDED = 2 +} google_protobuf_FeatureSet_RepeatedFieldEncoding; + +typedef enum { + google_protobuf_FeatureSet_UTF8_VALIDATION_UNKNOWN = 0, + google_protobuf_FeatureSet_VERIFY = 2, + google_protobuf_FeatureSet_NONE = 3 +} google_protobuf_FeatureSet_Utf8Validation; + +typedef enum { + google_protobuf_FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN = 0, + google_protobuf_FeatureSet_VisibilityFeature_EXPORT_ALL = 1, + google_protobuf_FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL = 2, + google_protobuf_FeatureSet_VisibilityFeature_LOCAL_ALL = 3, + google_protobuf_FeatureSet_VisibilityFeature_STRICT = 4 +} google_protobuf_FeatureSet_VisibilityFeature_DefaultSymbolVisibility; + +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + +typedef enum { + google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, + google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, + google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3, + google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4, + google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5, + google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6, + google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7, + google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8, + google_protobuf_FieldDescriptorProto_TYPE_STRING = 9, + google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10, + google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11, + google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12, + google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13, + google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15, + google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16, + google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17, + google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 +} google_protobuf_FieldDescriptorProto_Type; + +typedef enum { + google_protobuf_FieldOptions_STRING = 0, + google_protobuf_FieldOptions_CORD = 1, + google_protobuf_FieldOptions_STRING_PIECE = 2 +} google_protobuf_FieldOptions_CType; + +typedef enum { + google_protobuf_FieldOptions_JS_NORMAL = 0, + google_protobuf_FieldOptions_JS_STRING = 1, + google_protobuf_FieldOptions_JS_NUMBER = 2 +} google_protobuf_FieldOptions_JSType; + +typedef enum { + google_protobuf_FieldOptions_RETENTION_UNKNOWN = 0, + google_protobuf_FieldOptions_RETENTION_RUNTIME = 1, + google_protobuf_FieldOptions_RETENTION_SOURCE = 2 +} google_protobuf_FieldOptions_OptionRetention; + +typedef enum { + google_protobuf_FieldOptions_TARGET_TYPE_UNKNOWN = 0, + google_protobuf_FieldOptions_TARGET_TYPE_FILE = 1, + google_protobuf_FieldOptions_TARGET_TYPE_EXTENSION_RANGE = 2, + google_protobuf_FieldOptions_TARGET_TYPE_MESSAGE = 3, + google_protobuf_FieldOptions_TARGET_TYPE_FIELD = 4, + google_protobuf_FieldOptions_TARGET_TYPE_ONEOF = 5, + google_protobuf_FieldOptions_TARGET_TYPE_ENUM = 6, + google_protobuf_FieldOptions_TARGET_TYPE_ENUM_ENTRY = 7, + google_protobuf_FieldOptions_TARGET_TYPE_SERVICE = 8, + google_protobuf_FieldOptions_TARGET_TYPE_METHOD = 9 +} google_protobuf_FieldOptions_OptionTargetType; + +typedef enum { + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; + +typedef enum { + google_protobuf_GeneratedCodeInfo_Annotation_NONE = 0, + google_protobuf_GeneratedCodeInfo_Annotation_SET = 1, + google_protobuf_GeneratedCodeInfo_Annotation_ALIAS = 2 +} google_protobuf_GeneratedCodeInfo_Annotation_Semantic; + +typedef enum { + google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, + google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, + google_protobuf_MethodOptions_IDEMPOTENT = 2 +} google_protobuf_MethodOptions_IdempotencyLevel; + +typedef enum { + google_protobuf_VISIBILITY_UNSET = 0, + google_protobuf_VISIBILITY_LOCAL = 1, + google_protobuf_VISIBILITY_EXPORT = 2 +} google_protobuf_SymbolVisibility; + + + +/* google.protobuf.FileDescriptorSet */ +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_new(upb_Arena* arena) { + return (google_protobuf_FileDescriptorSet*)_upb_Message_New(&google__protobuf__FileDescriptorSet_msg_init, arena); +} +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FileDescriptorSet* ret = google_protobuf_FileDescriptorSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorSet_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FileDescriptorSet* google_protobuf_FileDescriptorSet_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileDescriptorSet* ret = google_protobuf_FileDescriptorSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorSet_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorSet_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FileDescriptorSet_serialize_ex(const google_protobuf_FileDescriptorSet* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorSet_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FileDescriptorSet_clear_file(google_protobuf_FileDescriptorSet* msg) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FileDescriptorProto* const* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet* msg, + size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FileDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorSet_file_upb_array( + const google_protobuf_FileDescriptorSet* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorSet_file_mutable_upb_array( + google_protobuf_FileDescriptorSet* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_mutable_file(google_protobuf_FileDescriptorSet* msg, + size_t* size) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FileDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + return (google_protobuf_FileDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file( + google_protobuf_FileDescriptorSet* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FileDescriptorProto* sub = + (struct google_protobuf_FileDescriptorProto*)_upb_Message_New(&google__protobuf__FileDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.FileDescriptorProto */ +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_FileDescriptorProto*)_upb_Message_New(&google__protobuf__FileDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FileDescriptorProto* ret = google_protobuf_FileDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileDescriptorProto* ret = google_protobuf_FileDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FileDescriptorProto_serialize_ex(const google_protobuf_FileDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_name(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_package(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_message_type(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_message_type_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_message_type_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_enum_type(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_enum_type_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_enum_type_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_service(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_ServiceDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_service_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_service_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_extension(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_extension_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_extension_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_options(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto* msg) { + const google_protobuf_FileOptions* default_val = NULL; + const google_protobuf_FileOptions* ret; + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_source_code_info(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto* msg) { + const google_protobuf_SourceCodeInfo* default_val = NULL; + const google_protobuf_SourceCodeInfo* ret; + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_public_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_public_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_public_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_weak_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_weak_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_weak_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_syntax(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_edition(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FileDescriptorProto_edition(const google_protobuf_FileDescriptorProto* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_has_edition(const google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_clear_option_dependency(google_protobuf_FileDescriptorProto* msg) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_FileDescriptorProto_option_dependency(const google_protobuf_FileDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileDescriptorProto_option_dependency_upb_array( + const google_protobuf_FileDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileDescriptorProto_option_dependency_mutable_upb_array( + google_protobuf_FileDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(56, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(64, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(12, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + return (google_protobuf_DescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(16, 72), 0, 33, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto* sub = + (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + return (google_protobuf_EnumDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(20, 80), 0, UPB_SIZE(31, 32), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumDescriptorProto* sub = + (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_ServiceDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + return (google_protobuf_ServiceDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(24, 88), 0, UPB_SIZE(29, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_ServiceDescriptorProto* sub = + (struct google_protobuf_ServiceDescriptorProto*)_upb_Message_New(&google__protobuf__ServiceDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + return (google_protobuf_FieldDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {7, UPB_SIZE(28, 96), 0, UPB_SIZE(27, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldDescriptorProto* sub = + (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto* msg, google_protobuf_FileOptions* value) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 104), 66, UPB_SIZE(25, 29), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FileOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FileOptions*)_upb_Message_New(&google__protobuf__FileOptions_msg_init, arena); + if (sub) google_protobuf_FileDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto* msg, google_protobuf_SourceCodeInfo* value) { + const upb_MiniTableField field = {9, UPB_SIZE(36, 112), 67, UPB_SIZE(23, 28), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info( + google_protobuf_FileDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg); + if (sub == NULL) { + sub = (struct google_protobuf_SourceCodeInfo*)_upb_Message_New(&google__protobuf__SourceCodeInfo_msg_init, arena); + if (sub) google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub); + } + return sub; +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(40, 120), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {11, UPB_SIZE(44, 128), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {12, UPB_SIZE(72, 48), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileDescriptorProto_set_edition(google_protobuf_FileDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {14, UPB_SIZE(48, 12), 69, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_mutable_option_dependency(google_protobuf_FileDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_FileDescriptorProto_resize_option_dependency(google_protobuf_FileDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FileDescriptorProto_add_option_dependency(google_protobuf_FileDescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {15, UPB_SIZE(52, 136), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} + +/* google.protobuf.DescriptorProto */ +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_DescriptorProto* ret = google_protobuf_DescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto* ret = google_protobuf_DescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_DescriptorProto_serialize_ex(const google_protobuf_DescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_name(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_field(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_field_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_field_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_nested_type(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_nested_type_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_nested_type_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_enum_type(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_enum_type_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_enum_type_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_extension_range(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto_ExtensionRange* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_extension_range_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_extension_range_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_extension(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_extension_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_extension_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_options(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto* msg) { + const google_protobuf_MessageOptions* default_val = NULL; + const google_protobuf_MessageOptions* ret; + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MessageOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_oneof_decl(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_OneofDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_oneof_decl_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_oneof_decl_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_reserved_range(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_DescriptorProto_ReservedRange* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_reserved_range_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_reserved_range_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_reserved_name(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_DescriptorProto_reserved_name_upb_array( + const google_protobuf_DescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_DescriptorProto_reserved_name_mutable_upb_array( + google_protobuf_DescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_DescriptorProto_clear_visibility(google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_visibility(const google_protobuf_DescriptorProto* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_has_visibility(const google_protobuf_DescriptorProto* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(52, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_field(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + return (google_protobuf_FieldDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(30, 31), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldDescriptorProto* sub = + (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + return (google_protobuf_DescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {3, UPB_SIZE(16, 40), 0, UPB_SIZE(28, 30), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto* sub = + (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + return (google_protobuf_EnumDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(26, 29), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumDescriptorProto* sub = + (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto_ExtensionRange**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + return (google_protobuf_DescriptorProto_ExtensionRange**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, UPB_SIZE(24, 28), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ExtensionRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto_ExtensionRange* sub = + (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ExtensionRange_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + return (google_protobuf_FieldDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(28, 64), 0, UPB_SIZE(22, 27), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldDescriptorProto* sub = + (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto* msg, google_protobuf_MessageOptions* value) { + const upb_MiniTableField field = {7, UPB_SIZE(32, 72), 65, UPB_SIZE(20, 26), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MessageOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MessageOptions*)_upb_Message_New(&google__protobuf__MessageOptions_msg_init, arena); + if (sub) google_protobuf_DescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_mutable_oneof_decl(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_OneofDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + return (google_protobuf_OneofDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {8, UPB_SIZE(36, 80), 0, UPB_SIZE(18, 25), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_OneofDescriptorProto* sub = + (struct google_protobuf_OneofDescriptorProto*)_upb_Message_New(&google__protobuf__OneofDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_DescriptorProto_ReservedRange**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + return (google_protobuf_DescriptorProto_ReservedRange**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range( + google_protobuf_DescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {9, UPB_SIZE(40, 88), 0, UPB_SIZE(16, 24), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__DescriptorProto__ReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_DescriptorProto_ReservedRange* sub = + (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ReservedRange_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE upb_StringView* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {10, UPB_SIZE(44, 96), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_DescriptorProto_set_visibility(google_protobuf_DescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 12), 66, UPB_SIZE(11, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.DescriptorProto.ExtensionRange */ +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ExtensionRange_msg_init, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_DescriptorProto_ExtensionRange* ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_ExtensionRange_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto_ExtensionRange* ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ExtensionRange_serialize_ex(const google_protobuf_DescriptorProto_ExtensionRange* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ExtensionRange_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_clear_start(google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_clear_end(google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_clear_options(google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const google_protobuf_ExtensionRangeOptions* default_val = NULL; + const google_protobuf_ExtensionRangeOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange* msg, google_protobuf_ExtensionRangeOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(20, 24), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options( + google_protobuf_DescriptorProto_ExtensionRange* msg, upb_Arena* arena) { + struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ExtensionRangeOptions*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions_msg_init, arena); + if (sub) google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.DescriptorProto.ReservedRange */ +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_new(upb_Arena* arena) { + return (google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ReservedRange_msg_init, arena); +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_DescriptorProto_ReservedRange* ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ReservedRange_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_ReservedRange_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_DescriptorProto_ReservedRange* ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__DescriptorProto__ReservedRange_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ReservedRange_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_DescriptorProto_ReservedRange_serialize_ex(const google_protobuf_DescriptorProto_ReservedRange* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__DescriptorProto__ReservedRange_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_clear_start(google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_clear_end(google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.ExtensionRangeOptions */ +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_new(upb_Arena* arena) { + return (google_protobuf_ExtensionRangeOptions*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions* ret = google_protobuf_ExtensionRangeOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ExtensionRangeOptions* google_protobuf_ExtensionRangeOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions* ret = google_protobuf_ExtensionRangeOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_serialize_ex(const google_protobuf_ExtensionRangeOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_declaration(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ExtensionRangeOptions_Declaration* const* google_protobuf_ExtensionRangeOptions_declaration(const google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_ExtensionRangeOptions_Declaration* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ExtensionRangeOptions_declaration_upb_array( + const google_protobuf_ExtensionRangeOptions* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ExtensionRangeOptions_declaration_mutable_upb_array( + google_protobuf_ExtensionRangeOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_verification(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_ExtensionRangeOptions_verification(const google_protobuf_ExtensionRangeOptions* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_has_verification(const google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_features(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_ExtensionRangeOptions_features(const google_protobuf_ExtensionRangeOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_has_features(const google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_clear_uninterpreted_option(google_protobuf_ExtensionRangeOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ExtensionRangeOptions_uninterpreted_option_upb_array( + const google_protobuf_ExtensionRangeOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ExtensionRangeOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_ExtensionRangeOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration** google_protobuf_ExtensionRangeOptions_mutable_declaration(google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_ExtensionRangeOptions_Declaration**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration** google_protobuf_ExtensionRangeOptions_resize_declaration(google_protobuf_ExtensionRangeOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + return (google_protobuf_ExtensionRangeOptions_Declaration**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_add_declaration( + google_protobuf_ExtensionRangeOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 16), 0, 12, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_ExtensionRangeOptions_Declaration* sub = + (struct google_protobuf_ExtensionRangeOptions_Declaration*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_verification(google_protobuf_ExtensionRangeOptions* msg, int32_t value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 64, UPB_SIZE(10, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_features(google_protobuf_ExtensionRangeOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {50, UPB_SIZE(20, 24), 65, UPB_SIZE(8, 10), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_ExtensionRangeOptions_mutable_features( + google_protobuf_ExtensionRangeOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_ExtensionRangeOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_ExtensionRangeOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_mutable_uninterpreted_option(google_protobuf_ExtensionRangeOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option( + google_protobuf_ExtensionRangeOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(24, 32), 0, UPB_SIZE(6, 9), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.ExtensionRangeOptions.Declaration */ +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_Declaration_new(upb_Arena* arena) { + return (google_protobuf_ExtensionRangeOptions_Declaration*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init, arena); +} +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_Declaration_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions_Declaration* ret = google_protobuf_ExtensionRangeOptions_Declaration_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ExtensionRangeOptions_Declaration* google_protobuf_ExtensionRangeOptions_Declaration_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ExtensionRangeOptions_Declaration* ret = google_protobuf_ExtensionRangeOptions_Declaration_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_Declaration_serialize(const google_protobuf_ExtensionRangeOptions_Declaration* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ExtensionRangeOptions_Declaration_serialize_ex(const google_protobuf_ExtensionRangeOptions_Declaration* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ExtensionRangeOptions__Declaration_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_number(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_ExtensionRangeOptions_Declaration_number(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_number(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_full_name(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_ExtensionRangeOptions_Declaration_full_name(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_full_name(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_type(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_ExtensionRangeOptions_Declaration_type(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_type(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_reserved(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_reserved(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_clear_repeated(google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_repeated(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ExtensionRangeOptions_Declaration_has_repeated(const google_protobuf_ExtensionRangeOptions_Declaration* msg) { + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_number(google_protobuf_ExtensionRangeOptions_Declaration* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_full_name(google_protobuf_ExtensionRangeOptions_Declaration* msg, upb_StringView value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_type(google_protobuf_ExtensionRangeOptions_Declaration* msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 32), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_reserved(google_protobuf_ExtensionRangeOptions_Declaration* msg, bool value) { + const upb_MiniTableField field = {5, 9, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ExtensionRangeOptions_Declaration_set_repeated(google_protobuf_ExtensionRangeOptions_Declaration* msg, bool value) { + const upb_MiniTableField field = {6, 10, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FieldDescriptorProto */ +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldDescriptorProto* ret = google_protobuf_FieldDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldDescriptorProto* google_protobuf_FieldDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldDescriptorProto* ret = google_protobuf_FieldDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldDescriptorProto_serialize_ex(const google_protobuf_FieldDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_name(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_extendee(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_number(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_label(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_type(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_type_name(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_default_value(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_options(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto* msg) { + const google_protobuf_FieldOptions* default_val = NULL; + const google_protobuf_FieldOptions* ret; + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_oneof_index(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_json_name(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_clear_proto3_optional(google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_proto3_optional(const google_protobuf_FieldDescriptorProto* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_proto3_optional(const google_protobuf_FieldDescriptorProto* msg) { + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, 32, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(40, 48), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {3, 12, 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {4, 16, 67, UPB_SIZE(24, 25), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {5, 20, 68, UPB_SIZE(22, 24), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {6, UPB_SIZE(48, 64), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {7, UPB_SIZE(56, 80), 70, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto* msg, google_protobuf_FieldOptions* value) { + const upb_MiniTableField field = {8, UPB_SIZE(24, 112), 71, UPB_SIZE(14, 17), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options( + google_protobuf_FieldDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions*)_upb_Message_New(&google__protobuf__FieldOptions_msg_init, arena); + if (sub) google_protobuf_FieldDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {9, UPB_SIZE(28, 24), 72, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {10, UPB_SIZE(64, 96), 73, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldDescriptorProto_set_proto3_optional(google_protobuf_FieldDescriptorProto* msg, bool value) { + const upb_MiniTableField field = {17, 10, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.OneofDescriptorProto */ +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_OneofDescriptorProto*)_upb_Message_New(&google__protobuf__OneofDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_OneofDescriptorProto* ret = google_protobuf_OneofDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_OneofDescriptorProto* google_protobuf_OneofDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_OneofDescriptorProto* ret = google_protobuf_OneofDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_OneofDescriptorProto_serialize_ex(const google_protobuf_OneofDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_clear_name(google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_clear_options(google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto* msg) { + const google_protobuf_OneofOptions* default_val = NULL; + const google_protobuf_OneofOptions* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto* msg, google_protobuf_OneofOptions* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 65, 3, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__OneofOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options( + google_protobuf_OneofDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_OneofOptions*)_upb_Message_New(&google__protobuf__OneofOptions_msg_init, arena); + if (sub) google_protobuf_OneofDescriptorProto_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.EnumDescriptorProto */ +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumDescriptorProto* ret = google_protobuf_EnumDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumDescriptorProto* google_protobuf_EnumDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumDescriptorProto* ret = google_protobuf_EnumDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_serialize_ex(const google_protobuf_EnumDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_name(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_value(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumValueDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumDescriptorProto_value_upb_array( + const google_protobuf_EnumDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumDescriptorProto_value_mutable_upb_array( + google_protobuf_EnumDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_options(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto* msg) { + const google_protobuf_EnumOptions* default_val = NULL; + const google_protobuf_EnumOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_reserved_range(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumDescriptorProto_reserved_range_upb_array( + const google_protobuf_EnumDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumDescriptorProto_reserved_range_mutable_upb_array( + google_protobuf_EnumDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_reserved_name(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumDescriptorProto_reserved_name_upb_array( + const google_protobuf_EnumDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumDescriptorProto_reserved_name_mutable_upb_array( + google_protobuf_EnumDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_clear_visibility(google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_visibility(const google_protobuf_EnumDescriptorProto* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_visibility(const google_protobuf_EnumDescriptorProto* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_mutable_value(google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumValueDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + return (google_protobuf_EnumValueDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value( + google_protobuf_EnumDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, 15, 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumValueDescriptorProto* sub = + (struct google_protobuf_EnumValueDescriptorProto*)_upb_Message_New(&google__protobuf__EnumValueDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto* msg, google_protobuf_EnumOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(13, 14), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options( + google_protobuf_EnumDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumOptions*)_upb_Message_New(&google__protobuf__EnumOptions_msg_init, arena); + if (sub) google_protobuf_EnumDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_mutable_reserved_range(google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range( + google_protobuf_EnumDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {4, UPB_SIZE(20, 48), 0, UPB_SIZE(11, 13), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = + (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_New(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE upb_StringView* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {5, UPB_SIZE(24, 56), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_set_visibility(google_protobuf_EnumDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {6, UPB_SIZE(28, 12), 66, UPB_SIZE(6, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.EnumDescriptorProto.EnumReservedRange */ +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_Arena* arena) { + return (google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_New(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumDescriptorProto_EnumReservedRange* ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize_ex(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_clear_start(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_clear_end(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange* msg) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.EnumValueDescriptorProto */ +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_EnumValueDescriptorProto*)_upb_Message_New(&google__protobuf__EnumValueDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumValueDescriptorProto* ret = google_protobuf_EnumValueDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumValueDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumValueDescriptorProto* ret = google_protobuf_EnumValueDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumValueDescriptorProto_serialize_ex(const google_protobuf_EnumValueDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_clear_name(google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_clear_number(google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_clear_options(google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto* msg) { + const google_protobuf_EnumValueOptions* default_val = NULL; + const google_protobuf_EnumValueOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto* msg, int32_t value) { + const upb_MiniTableField field = {2, 12, 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto* msg, google_protobuf_EnumValueOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 32), 66, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__EnumValueOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options( + google_protobuf_EnumValueDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_EnumValueOptions*)_upb_Message_New(&google__protobuf__EnumValueOptions_msg_init, arena); + if (sub) google_protobuf_EnumValueDescriptorProto_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.ServiceDescriptorProto */ +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_ServiceDescriptorProto*)_upb_Message_New(&google__protobuf__ServiceDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ServiceDescriptorProto* ret = google_protobuf_ServiceDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ServiceDescriptorProto* google_protobuf_ServiceDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ServiceDescriptorProto* ret = google_protobuf_ServiceDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ServiceDescriptorProto_serialize_ex(const google_protobuf_ServiceDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_clear_name(google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_clear_method(google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_MethodDescriptorProto* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ServiceDescriptorProto_method_upb_array( + const google_protobuf_ServiceDescriptorProto* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ServiceDescriptorProto_method_mutable_upb_array( + google_protobuf_ServiceDescriptorProto* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_clear_options(google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto* msg) { + const google_protobuf_ServiceOptions* default_val = NULL; + const google_protobuf_ServiceOptions* ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(20, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_mutable_method(google_protobuf_ServiceDescriptorProto* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_MethodDescriptorProto**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + return (google_protobuf_MethodDescriptorProto**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method( + google_protobuf_ServiceDescriptorProto* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 32), 0, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodDescriptorProto_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_MethodDescriptorProto* sub = + (struct google_protobuf_MethodDescriptorProto*)_upb_Message_New(&google__protobuf__MethodDescriptorProto_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto* msg, google_protobuf_ServiceOptions* value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 40), 65, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__ServiceOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options( + google_protobuf_ServiceDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_ServiceOptions*)_upb_Message_New(&google__protobuf__ServiceOptions_msg_init, arena); + if (sub) google_protobuf_ServiceDescriptorProto_set_options(msg, sub); + } + return sub; +} + +/* google.protobuf.MethodDescriptorProto */ +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_new(upb_Arena* arena) { + return (google_protobuf_MethodDescriptorProto*)_upb_Message_New(&google__protobuf__MethodDescriptorProto_msg_init, arena); +} +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_MethodDescriptorProto* ret = google_protobuf_MethodDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodDescriptorProto_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_MethodDescriptorProto* google_protobuf_MethodDescriptorProto_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MethodDescriptorProto* ret = google_protobuf_MethodDescriptorProto_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodDescriptorProto_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodDescriptorProto_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_MethodDescriptorProto_serialize_ex(const google_protobuf_MethodDescriptorProto* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodDescriptorProto_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_name(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_input_type(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_output_type(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_options(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto* msg) { + const google_protobuf_MethodOptions* default_val = NULL; + const google_protobuf_MethodOptions* ret; + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodOptions_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_client_streaming(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_clear_server_streaming(google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto* msg) { + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {1, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(24, 32), 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto* msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(32, 48), 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto* msg, google_protobuf_MethodOptions* value) { + const upb_MiniTableField field = {4, UPB_SIZE(12, 64), 67, 9, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__MethodOptions_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options( + google_protobuf_MethodDescriptorProto* msg, upb_Arena* arena) { + struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg); + if (sub == NULL) { + sub = (struct google_protobuf_MethodOptions*)_upb_Message_New(&google__protobuf__MethodOptions_msg_init, arena); + if (sub) google_protobuf_MethodDescriptorProto_set_options(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto* msg, bool value) { + const upb_MiniTableField field = {5, 9, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto* msg, bool value) { + const upb_MiniTableField field = {6, 10, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FileOptions */ +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_new(upb_Arena* arena) { + return (google_protobuf_FileOptions*)_upb_Message_New(&google__protobuf__FileOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FileOptions* google_protobuf_FileOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FileOptions* ret = google_protobuf_FileOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FileOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FileOptions_serialize_ex(const google_protobuf_FileOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FileOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_package(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_outer_classname(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_optimize_for(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions* msg) { + int32_t default_val = 1; + int32_t ret; + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_multiple_files(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_go_package(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_cc_generic_services(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_generic_services(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_py_generic_services(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_generate_equals_and_hash(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_deprecated(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_java_string_check_utf8(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_cc_enable_arenas(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions* msg) { + bool default_val = true; + bool ret; + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_objc_class_prefix(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_csharp_namespace(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_swift_prefix(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_php_class_prefix(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_php_namespace(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_php_metadata_namespace(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_ruby_package(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_features(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FileOptions_features(const google_protobuf_FileOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FileOptions_has_features(const google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FileOptions_clear_uninterpreted_option(google_protobuf_FileOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FileOptions_uninterpreted_option_upb_array( + const google_protobuf_FileOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FileOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_FileOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(32, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {8, 40, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions* msg, int32_t value) { + const upb_MiniTableField field = {9, 20, 66, UPB_SIZE(57, 58), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {10, 11, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {11, UPB_SIZE(48, 56), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {16, 12, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {17, 13, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {18, 14, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {20, 15, 72, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {23, 16, 73, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {27, 17, 74, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions* msg, bool value) { + const upb_MiniTableField field = {31, 18, 75, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {36, UPB_SIZE(56, 72), 76, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {37, UPB_SIZE(64, 88), 77, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {39, UPB_SIZE(72, 104), 78, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {40, UPB_SIZE(80, 120), 79, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {41, UPB_SIZE(88, 136), 80, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {44, UPB_SIZE(96, 152), 81, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {45, UPB_SIZE(104, 168), 82, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FileOptions_set_features(google_protobuf_FileOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {50, UPB_SIZE(24, 184), 83, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FileOptions_mutable_features( + google_protobuf_FileOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FileOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FileOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option( + google_protobuf_FileOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(28, 192), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.MessageOptions */ +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_new(upb_Arena* arena) { + return (google_protobuf_MessageOptions*)_upb_Message_New(&google__protobuf__MessageOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_MessageOptions* ret = google_protobuf_MessageOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MessageOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_MessageOptions* google_protobuf_MessageOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MessageOptions* ret = google_protobuf_MessageOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MessageOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MessageOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_MessageOptions_serialize_ex(const google_protobuf_MessageOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MessageOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_MessageOptions_clear_message_set_wire_format(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_no_standard_descriptor_accessor(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_deprecated(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_map_entry(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_deprecated_legacy_json_field_conflicts(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MessageOptions_deprecated_legacy_json_field_conflicts(const google_protobuf_MessageOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated_legacy_json_field_conflicts(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_features(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_MessageOptions_features(const google_protobuf_MessageOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MessageOptions_has_features(const google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MessageOptions_clear_uninterpreted_option(google_protobuf_MessageOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_MessageOptions_uninterpreted_option_upb_array( + const google_protobuf_MessageOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_MessageOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_MessageOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {7, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_deprecated_legacy_json_field_conflicts(google_protobuf_MessageOptions* msg, bool value) { + const upb_MiniTableField field = {11, 13, 68, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MessageOptions_set_features(google_protobuf_MessageOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {12, 16, 69, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_MessageOptions_mutable_features( + google_protobuf_MessageOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_MessageOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_MessageOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option( + google_protobuf_MessageOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.FieldOptions */ +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions*)_upb_Message_New(&google__protobuf__FieldOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldOptions* google_protobuf_FieldOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions* ret = google_protobuf_FieldOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldOptions_serialize_ex(const google_protobuf_FieldOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldOptions_clear_ctype(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_packed(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_deprecated(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_lazy(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_jstype(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_weak(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_unverified_lazy(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_unverified_lazy(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_unverified_lazy(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_debug_redact(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_FieldOptions_debug_redact(const google_protobuf_FieldOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_debug_redact(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_retention(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_retention(const google_protobuf_FieldOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_retention(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_targets(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_FieldOptions_targets(const google_protobuf_FieldOptions* msg, + size_t* size) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FieldOptions_targets_upb_array( + const google_protobuf_FieldOptions* msg, size_t* size) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FieldOptions_targets_mutable_upb_array( + google_protobuf_FieldOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FieldOptions_clear_edition_defaults(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions_EditionDefault* const* google_protobuf_FieldOptions_edition_defaults(const google_protobuf_FieldOptions* msg, + size_t* size) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FieldOptions_EditionDefault* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FieldOptions_edition_defaults_upb_array( + const google_protobuf_FieldOptions* msg, size_t* size) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FieldOptions_edition_defaults_mutable_upb_array( + google_protobuf_FieldOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FieldOptions_clear_features(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FieldOptions_features(const google_protobuf_FieldOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_features(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_feature_support(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_feature_support(const google_protobuf_FieldOptions* msg) { + const google_protobuf_FieldOptions_FeatureSupport* default_val = NULL; + const google_protobuf_FieldOptions_FeatureSupport* ret; + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_has_feature_support(const google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_clear_uninterpreted_option(google_protobuf_FieldOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FieldOptions_uninterpreted_option_upb_array( + const google_protobuf_FieldOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FieldOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_FieldOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions* msg, int32_t value) { + const upb_MiniTableField field = {1, 16, 64, 42, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {2, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {3, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {5, 12, 67, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions* msg, int32_t value) { + const upb_MiniTableField field = {6, 20, 68, UPB_SIZE(31, 32), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {10, 13, 69, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_unverified_lazy(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {15, 14, 70, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_debug_redact(google_protobuf_FieldOptions* msg, bool value) { + const upb_MiniTableField field = {16, 15, 71, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_set_retention(google_protobuf_FieldOptions* msg, int32_t value) { + const upb_MiniTableField field = {17, 24, 72, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE int32_t* google_protobuf_FieldOptions_mutable_targets(google_protobuf_FieldOptions* msg, + size_t* size) { + upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_FieldOptions_resize_targets(google_protobuf_FieldOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_FieldOptions_add_targets(google_protobuf_FieldOptions* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {19, UPB_SIZE(28, 32), 0, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE google_protobuf_FieldOptions_EditionDefault** google_protobuf_FieldOptions_mutable_edition_defaults(google_protobuf_FieldOptions* msg, + size_t* size) { + upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FieldOptions_EditionDefault**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FieldOptions_EditionDefault** google_protobuf_FieldOptions_resize_edition_defaults(google_protobuf_FieldOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + return (google_protobuf_FieldOptions_EditionDefault**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_add_edition_defaults( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {20, UPB_SIZE(32, 40), 0, UPB_SIZE(16, 20), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__EditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FieldOptions_EditionDefault* sub = + (struct google_protobuf_FieldOptions_EditionDefault*)_upb_Message_New(&google__protobuf__FieldOptions__EditionDefault_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_FieldOptions_set_features(google_protobuf_FieldOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {21, UPB_SIZE(36, 48), 73, UPB_SIZE(14, 19), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FieldOptions_mutable_features( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FieldOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FieldOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FieldOptions_set_feature_support(google_protobuf_FieldOptions* msg, google_protobuf_FieldOptions_FeatureSupport* value) { + const upb_MiniTableField field = {22, UPB_SIZE(40, 56), 74, UPB_SIZE(12, 18), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_mutable_feature_support( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + struct google_protobuf_FieldOptions_FeatureSupport* sub = (struct google_protobuf_FieldOptions_FeatureSupport*)google_protobuf_FieldOptions_feature_support(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions_FeatureSupport*)_upb_Message_New(&google__protobuf__FieldOptions__FeatureSupport_msg_init, arena); + if (sub) google_protobuf_FieldOptions_set_feature_support(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option( + google_protobuf_FieldOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(44, 64), 0, UPB_SIZE(10, 17), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.FieldOptions.EditionDefault */ +UPB_INLINE google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_EditionDefault_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions_EditionDefault*)_upb_Message_New(&google__protobuf__FieldOptions__EditionDefault_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_EditionDefault_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldOptions_EditionDefault* ret = google_protobuf_FieldOptions_EditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__EditionDefault_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldOptions_EditionDefault* google_protobuf_FieldOptions_EditionDefault_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions_EditionDefault* ret = google_protobuf_FieldOptions_EditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__EditionDefault_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldOptions_EditionDefault_serialize(const google_protobuf_FieldOptions_EditionDefault* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__EditionDefault_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldOptions_EditionDefault_serialize_ex(const google_protobuf_FieldOptions_EditionDefault* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__EditionDefault_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_clear_value(google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldOptions_EditionDefault_value(const google_protobuf_FieldOptions_EditionDefault* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_EditionDefault_has_value(const google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_clear_edition(google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_EditionDefault_edition(const google_protobuf_FieldOptions_EditionDefault* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_EditionDefault_has_edition(const google_protobuf_FieldOptions_EditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_set_value(google_protobuf_FieldOptions_EditionDefault* msg, upb_StringView value) { + const upb_MiniTableField field = {2, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_EditionDefault_set_edition(google_protobuf_FieldOptions_EditionDefault* msg, int32_t value) { + const upb_MiniTableField field = {3, 12, 65, 3, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FieldOptions.FeatureSupport */ +UPB_INLINE google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_FeatureSupport_new(upb_Arena* arena) { + return (google_protobuf_FieldOptions_FeatureSupport*)_upb_Message_New(&google__protobuf__FieldOptions__FeatureSupport_msg_init, arena); +} +UPB_INLINE google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_FeatureSupport_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FieldOptions_FeatureSupport* ret = google_protobuf_FieldOptions_FeatureSupport_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__FeatureSupport_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FieldOptions_FeatureSupport* google_protobuf_FieldOptions_FeatureSupport_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FieldOptions_FeatureSupport* ret = google_protobuf_FieldOptions_FeatureSupport_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FieldOptions__FeatureSupport_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FieldOptions_FeatureSupport_serialize(const google_protobuf_FieldOptions_FeatureSupport* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__FeatureSupport_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FieldOptions_FeatureSupport_serialize_ex(const google_protobuf_FieldOptions_FeatureSupport* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FieldOptions__FeatureSupport_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_edition_introduced(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_FeatureSupport_edition_introduced(const google_protobuf_FieldOptions_FeatureSupport* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_edition_introduced(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_edition_deprecated(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_FeatureSupport_edition_deprecated(const google_protobuf_FieldOptions_FeatureSupport* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_edition_deprecated(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_deprecation_warning(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldOptions_FeatureSupport_deprecation_warning(const google_protobuf_FieldOptions_FeatureSupport* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_deprecation_warning(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_edition_removed(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FieldOptions_FeatureSupport_edition_removed(const google_protobuf_FieldOptions_FeatureSupport* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_edition_removed(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_clear_removal_error(google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_FieldOptions_FeatureSupport_removal_error(const google_protobuf_FieldOptions_FeatureSupport* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FieldOptions_FeatureSupport_has_removal_error(const google_protobuf_FieldOptions_FeatureSupport* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_edition_introduced(google_protobuf_FieldOptions_FeatureSupport* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, UPB_SIZE(15, 16), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_edition_deprecated(google_protobuf_FieldOptions_FeatureSupport* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(13, 15), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_deprecation_warning(google_protobuf_FieldOptions_FeatureSupport* msg, upb_StringView value) { + const upb_MiniTableField field = {3, 24, 66, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_edition_removed(google_protobuf_FieldOptions_FeatureSupport* msg, int32_t value) { + const upb_MiniTableField field = {4, 20, 67, UPB_SIZE(8, 11), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FieldOptions_FeatureSupport_set_removal_error(google_protobuf_FieldOptions_FeatureSupport* msg, upb_StringView value) { + const upb_MiniTableField field = {5, UPB_SIZE(32, 40), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.OneofOptions */ +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_new(upb_Arena* arena) { + return (google_protobuf_OneofOptions*)_upb_Message_New(&google__protobuf__OneofOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_OneofOptions* google_protobuf_OneofOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_OneofOptions* ret = google_protobuf_OneofOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__OneofOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_OneofOptions_serialize_ex(const google_protobuf_OneofOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__OneofOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_OneofOptions_clear_features(google_protobuf_OneofOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_OneofOptions_features(const google_protobuf_OneofOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_OneofOptions_has_features(const google_protobuf_OneofOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_OneofOptions_clear_uninterpreted_option(google_protobuf_OneofOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_OneofOptions_uninterpreted_option_upb_array( + const google_protobuf_OneofOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_OneofOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_OneofOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_OneofOptions_set_features(google_protobuf_OneofOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, 6, 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_OneofOptions_mutable_features( + google_protobuf_OneofOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_OneofOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_OneofOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mutable_uninterpreted_option(google_protobuf_OneofOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option( + google_protobuf_OneofOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 5), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.EnumOptions */ +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_new(upb_Arena* arena) { + return (google_protobuf_EnumOptions*)_upb_Message_New(&google__protobuf__EnumOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumOptions* google_protobuf_EnumOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumOptions* ret = google_protobuf_EnumOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumOptions_serialize_ex(const google_protobuf_EnumOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumOptions_clear_allow_alias(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_deprecated(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_deprecated_legacy_json_field_conflicts(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumOptions_deprecated_legacy_json_field_conflicts(const google_protobuf_EnumOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated_legacy_json_field_conflicts(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_features(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_EnumOptions_features(const google_protobuf_EnumOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumOptions_has_features(const google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumOptions_clear_uninterpreted_option(google_protobuf_EnumOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumOptions_uninterpreted_option_upb_array( + const google_protobuf_EnumOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_EnumOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions* msg, bool value) { + const upb_MiniTableField field = {2, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions* msg, bool value) { + const upb_MiniTableField field = {3, 10, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumOptions_set_deprecated_legacy_json_field_conflicts(google_protobuf_EnumOptions* msg, bool value) { + const upb_MiniTableField field = {6, 11, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumOptions_set_features(google_protobuf_EnumOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {7, UPB_SIZE(12, 16), 67, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_EnumOptions_mutable_features( + google_protobuf_EnumOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_EnumOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_EnumOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option( + google_protobuf_EnumOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.EnumValueOptions */ +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_new(upb_Arena* arena) { + return (google_protobuf_EnumValueOptions*)_upb_Message_New(&google__protobuf__EnumValueOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_EnumValueOptions* ret = google_protobuf_EnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_EnumValueOptions* google_protobuf_EnumValueOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_EnumValueOptions* ret = google_protobuf_EnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__EnumValueOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_EnumValueOptions_serialize_ex(const google_protobuf_EnumValueOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__EnumValueOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_deprecated(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_features(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_EnumValueOptions_features(const google_protobuf_EnumValueOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_features(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_debug_redact(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_EnumValueOptions_debug_redact(const google_protobuf_EnumValueOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_debug_redact(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_feature_support(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FieldOptions_FeatureSupport* google_protobuf_EnumValueOptions_feature_support(const google_protobuf_EnumValueOptions* msg) { + const google_protobuf_FieldOptions_FeatureSupport* default_val = NULL; + const google_protobuf_FieldOptions_FeatureSupport* ret; + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_EnumValueOptions_has_feature_support(const google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_EnumValueOptions_clear_uninterpreted_option(google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_EnumValueOptions_uninterpreted_option_upb_array( + const google_protobuf_EnumValueOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_EnumValueOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_EnumValueOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions* msg, bool value) { + const upb_MiniTableField field = {1, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_features(google_protobuf_EnumValueOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 16), 65, UPB_SIZE(12, 13), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_EnumValueOptions_mutable_features( + google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_EnumValueOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_EnumValueOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_debug_redact(google_protobuf_EnumValueOptions* msg, bool value) { + const upb_MiniTableField field = {3, 10, 66, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_EnumValueOptions_set_feature_support(google_protobuf_EnumValueOptions* msg, google_protobuf_FieldOptions_FeatureSupport* value) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 24), 67, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FieldOptions__FeatureSupport_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FieldOptions_FeatureSupport* google_protobuf_EnumValueOptions_mutable_feature_support( + google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + struct google_protobuf_FieldOptions_FeatureSupport* sub = (struct google_protobuf_FieldOptions_FeatureSupport*)google_protobuf_EnumValueOptions_feature_support(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FieldOptions_FeatureSupport*)_upb_Message_New(&google__protobuf__FieldOptions__FeatureSupport_msg_init, arena); + if (sub) google_protobuf_EnumValueOptions_set_feature_support(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option( + google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 32), 0, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.ServiceOptions */ +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_new(upb_Arena* arena) { + return (google_protobuf_ServiceOptions*)_upb_Message_New(&google__protobuf__ServiceOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_ServiceOptions* ret = google_protobuf_ServiceOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_ServiceOptions* google_protobuf_ServiceOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_ServiceOptions* ret = google_protobuf_ServiceOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__ServiceOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_ServiceOptions_serialize_ex(const google_protobuf_ServiceOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__ServiceOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_ServiceOptions_clear_deprecated(google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ServiceOptions_clear_features(google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_ServiceOptions_features(const google_protobuf_ServiceOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_ServiceOptions_has_features(const google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_ServiceOptions_clear_uninterpreted_option(google_protobuf_ServiceOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_ServiceOptions_uninterpreted_option_upb_array( + const google_protobuf_ServiceOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_ServiceOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_ServiceOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions* msg, bool value) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_ServiceOptions_set_features(google_protobuf_ServiceOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {34, UPB_SIZE(12, 16), 65, UPB_SIZE(6, 7), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_ServiceOptions_mutable_features( + google_protobuf_ServiceOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_ServiceOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_ServiceOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option( + google_protobuf_ServiceOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(16, 24), 0, UPB_SIZE(4, 6), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.MethodOptions */ +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_new(upb_Arena* arena) { + return (google_protobuf_MethodOptions*)_upb_Message_New(&google__protobuf__MethodOptions_msg_init, arena); +} +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_MethodOptions* google_protobuf_MethodOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_MethodOptions* ret = google_protobuf_MethodOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__MethodOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_MethodOptions_serialize_ex(const google_protobuf_MethodOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__MethodOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_MethodOptions_clear_deprecated(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodOptions_clear_idempotency_level(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodOptions_clear_features(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_MethodOptions_features(const google_protobuf_MethodOptions* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_MethodOptions_has_features(const google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_MethodOptions_clear_uninterpreted_option(google_protobuf_MethodOptions* msg) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions* msg, + size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_MethodOptions_uninterpreted_option_upb_array( + const google_protobuf_MethodOptions* msg, size_t* size) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_MethodOptions_uninterpreted_option_mutable_upb_array( + google_protobuf_MethodOptions* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions* msg, bool value) { + const upb_MiniTableField field = {33, 9, 64, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions* msg, int32_t value) { + const upb_MiniTableField field = {34, 12, 65, 9, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_MethodOptions_set_features(google_protobuf_MethodOptions* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {35, 16, 66, UPB_SIZE(7, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_MethodOptions_mutable_features( + google_protobuf_MethodOptions* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_MethodOptions_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_MethodOptions_set_features(msg, sub); + } + return sub; +} +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions* msg, + size_t* size) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + return (google_protobuf_UninterpretedOption**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option( + google_protobuf_MethodOptions* msg, upb_Arena* arena) { + upb_MiniTableField field = {999, UPB_SIZE(20, 24), 0, UPB_SIZE(5, 7), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption* sub = + (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.UninterpretedOption */ +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_new(upb_Arena* arena) { + return (google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_UninterpretedOption* ret = google_protobuf_UninterpretedOption_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_UninterpretedOption* google_protobuf_UninterpretedOption_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_UninterpretedOption* ret = google_protobuf_UninterpretedOption_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_serialize_ex(const google_protobuf_UninterpretedOption* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_name(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_UninterpretedOption_NamePart* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_UninterpretedOption_name_upb_array( + const google_protobuf_UninterpretedOption* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_UninterpretedOption_name_mutable_upb_array( + google_protobuf_UninterpretedOption* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_identifier_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_positive_int_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption* msg) { + uint64_t default_val = (uint64_t)0ull; + uint64_t ret; + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_negative_int_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption* msg) { + int64_t default_val = (int64_t)0ll; + int64_t ret; + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_double_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption* msg) { + double default_val = 0; + double ret; + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_string_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_clear_aggregate_value(google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption* msg) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_UninterpretedOption_NamePart**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + return (google_protobuf_UninterpretedOption_NamePart**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name( + google_protobuf_UninterpretedOption* msg, upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(12, 64), 0, UPB_SIZE(21, 22), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__UninterpretedOption__NamePart_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_UninterpretedOption_NamePart* sub = + (struct google_protobuf_UninterpretedOption_NamePart*)_upb_Message_New(&google__protobuf__UninterpretedOption__NamePart_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption* msg, upb_StringView value) { + const upb_MiniTableField field = {3, 16, 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption* msg, uint64_t value) { + const upb_MiniTableField field = {4, UPB_SIZE(40, 72), 65, kUpb_NoSub, 4, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption* msg, int64_t value) { + const upb_MiniTableField field = {5, UPB_SIZE(48, 80), 66, kUpb_NoSub, 3, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption* msg, double value) { + const upb_MiniTableField field = {6, UPB_SIZE(56, 88), 67, kUpb_NoSub, 1, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_8Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption* msg, upb_StringView value) { + const upb_MiniTableField field = {7, UPB_SIZE(24, 32), 68, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption* msg, upb_StringView value) { + const upb_MiniTableField field = {8, UPB_SIZE(32, 48), 69, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.UninterpretedOption.NamePart */ +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_new(upb_Arena* arena) { + return (google_protobuf_UninterpretedOption_NamePart*)_upb_Message_New(&google__protobuf__UninterpretedOption__NamePart_msg_init, arena); +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_UninterpretedOption_NamePart* ret = google_protobuf_UninterpretedOption_NamePart_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption__NamePart_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_NamePart_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_UninterpretedOption_NamePart* ret = google_protobuf_UninterpretedOption_NamePart_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__UninterpretedOption__NamePart_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption__NamePart_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_UninterpretedOption_NamePart_serialize_ex(const google_protobuf_UninterpretedOption_NamePart* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__UninterpretedOption__NamePart_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_clear_name_part(google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_clear_is_extension(google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart* msg) { + bool default_val = false; + bool ret; + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart* msg) { + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart* msg, bool value) { + const upb_MiniTableField field = {2, 9, 65, kUpb_NoSub, 8, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FeatureSet */ +UPB_INLINE google_protobuf_FeatureSet* google_protobuf_FeatureSet_new(upb_Arena* arena) { + return (google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSet* google_protobuf_FeatureSet_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSet* ret = google_protobuf_FeatureSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSet* google_protobuf_FeatureSet_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSet* ret = google_protobuf_FeatureSet_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSet_serialize(const google_protobuf_FeatureSet* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSet_serialize_ex(const google_protobuf_FeatureSet* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FeatureSet_clear_field_presence(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_field_presence(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_field_presence(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_enum_type(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_enum_type(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_enum_type(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_repeated_field_encoding(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_repeated_field_encoding(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_utf8_validation(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_utf8_validation(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_utf8_validation(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_message_encoding(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_message_encoding(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_message_encoding(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_json_format(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_json_format(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_json_format(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_enforce_naming_style(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_enforce_naming_style(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_enforce_naming_style(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSet_clear_default_symbol_visibility(google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSet_default_symbol_visibility(const google_protobuf_FeatureSet* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSet_has_default_symbol_visibility(const google_protobuf_FeatureSet* msg) { + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FeatureSet_set_field_presence(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {1, 12, 64, 24, 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_enum_type(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {2, 16, 65, UPB_SIZE(22, 23), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_repeated_field_encoding(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {3, 20, 66, UPB_SIZE(20, 22), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_utf8_validation(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {4, 24, 67, UPB_SIZE(18, 21), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_message_encoding(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {5, 28, 68, UPB_SIZE(16, 20), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_json_format(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {6, 32, 69, UPB_SIZE(14, 19), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_enforce_naming_style(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {7, 36, 70, UPB_SIZE(12, 18), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSet_set_default_symbol_visibility(google_protobuf_FeatureSet* msg, int32_t value) { + const upb_MiniTableField field = {8, 40, 71, UPB_SIZE(10, 17), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FeatureSet.VisibilityFeature */ +UPB_INLINE google_protobuf_FeatureSet_VisibilityFeature* google_protobuf_FeatureSet_VisibilityFeature_new(upb_Arena* arena) { + return (google_protobuf_FeatureSet_VisibilityFeature*)_upb_Message_New(&google__protobuf__FeatureSet__VisibilityFeature_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSet_VisibilityFeature* google_protobuf_FeatureSet_VisibilityFeature_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSet_VisibilityFeature* ret = google_protobuf_FeatureSet_VisibilityFeature_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSet_VisibilityFeature* google_protobuf_FeatureSet_VisibilityFeature_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSet_VisibilityFeature* ret = google_protobuf_FeatureSet_VisibilityFeature_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSet_VisibilityFeature_serialize(const google_protobuf_FeatureSet_VisibilityFeature* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSet_VisibilityFeature_serialize_ex(const google_protobuf_FeatureSet_VisibilityFeature* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSet__VisibilityFeature_msg_init, options, arena, &ptr, len); + return ptr; +} + + +/* google.protobuf.FeatureSetDefaults */ +UPB_INLINE google_protobuf_FeatureSetDefaults* google_protobuf_FeatureSetDefaults_new(upb_Arena* arena) { + return (google_protobuf_FeatureSetDefaults*)_upb_Message_New(&google__protobuf__FeatureSetDefaults_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSetDefaults* google_protobuf_FeatureSetDefaults_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSetDefaults* ret = google_protobuf_FeatureSetDefaults_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSetDefaults* google_protobuf_FeatureSetDefaults_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSetDefaults* ret = google_protobuf_FeatureSetDefaults_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_serialize(const google_protobuf_FeatureSetDefaults* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_serialize_ex(const google_protobuf_FeatureSetDefaults* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_clear_defaults(google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* google_protobuf_FeatureSetDefaults_defaults(const google_protobuf_FeatureSetDefaults* msg, + size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_FeatureSetDefaults_defaults_upb_array( + const google_protobuf_FeatureSetDefaults* msg, size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_FeatureSetDefaults_defaults_mutable_upb_array( + google_protobuf_FeatureSetDefaults* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_clear_minimum_edition(google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSetDefaults_minimum_edition(const google_protobuf_FeatureSetDefaults* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_has_minimum_edition(const google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_clear_maximum_edition(google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSetDefaults_maximum_edition(const google_protobuf_FeatureSetDefaults* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_has_maximum_edition(const google_protobuf_FeatureSetDefaults* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault** google_protobuf_FeatureSetDefaults_mutable_defaults(google_protobuf_FeatureSetDefaults* msg, + size_t* size) { + upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault** google_protobuf_FeatureSetDefaults_resize_defaults(google_protobuf_FeatureSetDefaults* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + return (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_add_defaults( + google_protobuf_FeatureSetDefaults* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 24), 0, UPB_SIZE(9, 10), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* sub = + (struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault*)_upb_Message_New(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_set_minimum_edition(google_protobuf_FeatureSetDefaults* msg, int32_t value) { + const upb_MiniTableField field = {4, UPB_SIZE(16, 12), 64, UPB_SIZE(7, 9), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_set_maximum_edition(google_protobuf_FeatureSetDefaults* msg, int32_t value) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 16), 65, UPB_SIZE(5, 8), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault */ +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_new(upb_Arena* arena) { + return (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault*)_upb_Message_New(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, arena); +} +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* ret = google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* ret = google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_serialize(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_serialize_ex(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_clear_edition(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_has_edition(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_clear_overridable_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_overridable_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_has_overridable_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_clear_fixed_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_fixed_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const google_protobuf_FeatureSet* default_val = NULL; + const google_protobuf_FeatureSet* ret; + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_has_fixed_features(const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_edition(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, int32_t value) { + const upb_MiniTableField field = {3, 12, 64, UPB_SIZE(9, 10), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_overridable_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {4, 16, 65, UPB_SIZE(7, 9), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_mutable_overridable_features( + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_overridable_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_overridable_features(msg, sub); + } + return sub; +} +UPB_INLINE void google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_fixed_features(google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, google_protobuf_FeatureSet* value) { + const upb_MiniTableField field = {5, UPB_SIZE(20, 24), 66, UPB_SIZE(5, 8), 11, (int)kUpb_FieldMode_Scalar | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__FeatureSet_msg_init); + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE struct google_protobuf_FeatureSet* google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_mutable_fixed_features( + google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* msg, upb_Arena* arena) { + struct google_protobuf_FeatureSet* sub = (struct google_protobuf_FeatureSet*)google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_fixed_features(msg); + if (sub == NULL) { + sub = (struct google_protobuf_FeatureSet*)_upb_Message_New(&google__protobuf__FeatureSet_msg_init, arena); + if (sub) google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_set_fixed_features(msg, sub); + } + return sub; +} + +/* google.protobuf.SourceCodeInfo */ +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_new(upb_Arena* arena) { + return (google_protobuf_SourceCodeInfo*)_upb_Message_New(&google__protobuf__SourceCodeInfo_msg_init, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_SourceCodeInfo* ret = google_protobuf_SourceCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_SourceCodeInfo* google_protobuf_SourceCodeInfo_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_SourceCodeInfo* ret = google_protobuf_SourceCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_serialize_ex(const google_protobuf_SourceCodeInfo* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_clear_location(google_protobuf_SourceCodeInfo* msg) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_SourceCodeInfo_Location* const* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo* msg, + size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_SourceCodeInfo_Location* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_location_upb_array( + const google_protobuf_SourceCodeInfo* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_location_mutable_upb_array( + google_protobuf_SourceCodeInfo* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_mutable_location(google_protobuf_SourceCodeInfo* msg, + size_t* size) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_SourceCodeInfo_Location**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + return (google_protobuf_SourceCodeInfo_Location**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location( + google_protobuf_SourceCodeInfo* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__SourceCodeInfo__Location_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_SourceCodeInfo_Location* sub = + (struct google_protobuf_SourceCodeInfo_Location*)_upb_Message_New(&google__protobuf__SourceCodeInfo__Location_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.SourceCodeInfo.Location */ +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_new(upb_Arena* arena) { + return (google_protobuf_SourceCodeInfo_Location*)_upb_Message_New(&google__protobuf__SourceCodeInfo__Location_msg_init, arena); +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_SourceCodeInfo_Location* ret = google_protobuf_SourceCodeInfo_Location_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo__Location_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_Location_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_SourceCodeInfo_Location* ret = google_protobuf_SourceCodeInfo_Location_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__SourceCodeInfo__Location_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo__Location_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_SourceCodeInfo_Location_serialize_ex(const google_protobuf_SourceCodeInfo_Location* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__SourceCodeInfo__Location_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_path(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_Location_path_upb_array( + const google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_Location_path_mutable_upb_array( + google_protobuf_SourceCodeInfo_Location* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_span(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_Location_span_upb_array( + const google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_Location_span_mutable_upb_array( + google_protobuf_SourceCodeInfo_Location* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_leading_comments(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_trailing_comments(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_clear_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_SourceCodeInfo_Location_leading_detached_comments_upb_array( + const google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_SourceCodeInfo_Location_leading_detached_comments_mutable_upb_array( + google_protobuf_SourceCodeInfo_Location* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 48), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {2, UPB_SIZE(16, 56), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location* msg, upb_StringView value) { + const upb_MiniTableField field = {3, UPB_SIZE(24, 16), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location* msg, upb_StringView value) { + const upb_MiniTableField field = {4, 32, 65, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE upb_StringView* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg, + size_t* size) { + upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (upb_StringView*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE upb_StringView* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (upb_StringView*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location* msg, upb_StringView val, + upb_Arena* arena) { + upb_MiniTableField field = {6, UPB_SIZE(20, 64), 0, kUpb_NoSub, 12, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsAlternate | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} + +/* google.protobuf.GeneratedCodeInfo */ +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_new(upb_Arena* arena) { + return (google_protobuf_GeneratedCodeInfo*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo_msg_init, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo* ret = google_protobuf_GeneratedCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_GeneratedCodeInfo* google_protobuf_GeneratedCodeInfo_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo* ret = google_protobuf_GeneratedCodeInfo_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_serialize_ex(const google_protobuf_GeneratedCodeInfo* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_clear_annotation(google_protobuf_GeneratedCodeInfo* msg) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE const google_protobuf_GeneratedCodeInfo_Annotation* const* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo* msg, + size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (const google_protobuf_GeneratedCodeInfo_Annotation* const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_GeneratedCodeInfo_annotation_upb_array( + const google_protobuf_GeneratedCodeInfo* msg, size_t* size) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_GeneratedCodeInfo_annotation_mutable_upb_array( + google_protobuf_GeneratedCodeInfo* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_mutable_annotation(google_protobuf_GeneratedCodeInfo* msg, + size_t* size) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (google_protobuf_GeneratedCodeInfo_Annotation**)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + return (google_protobuf_GeneratedCodeInfo_Annotation**)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation( + google_protobuf_GeneratedCodeInfo* msg, upb_Arena* arena) { + upb_MiniTableField field = {1, 8, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Array | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + UPB_PRIVATE(_upb_MiniTable_StrongReference)(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init); + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return NULL; + } + struct google_protobuf_GeneratedCodeInfo_Annotation* sub = + (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init, arena); + if (!arr || !sub) return NULL; + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &sub, sizeof(sub)); + return sub; +} + +/* google.protobuf.GeneratedCodeInfo.Annotation */ +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_new(upb_Arena* arena) { + return (google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init, arena); +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_parse(const char* buf, size_t size, + upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo_Annotation* ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_Annotation_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + google_protobuf_GeneratedCodeInfo_Annotation* ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* google_protobuf_GeneratedCodeInfo_Annotation_serialize_ex(const google_protobuf_GeneratedCodeInfo_Annotation* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_path(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation* msg, + size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t const*)upb_Array_DataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +// +UPB_INLINE const upb_Array* _google_protobuf_GeneratedCodeInfo_Annotation_path_upb_array( + const google_protobuf_GeneratedCodeInfo_Annotation* msg, size_t* size) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + const upb_Array* arr = upb_Message_GetArray(UPB_UPCAST(msg), &field); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} + +UPB_INLINE upb_Array* _google_protobuf_GeneratedCodeInfo_Annotation_path_mutable_upb_array( + google_protobuf_GeneratedCodeInfo_Annotation* msg, size_t* size, upb_Arena* arena) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray(UPB_UPCAST(msg), + &field, arena); + if (size) { + *size = arr ? arr->UPB_PRIVATE(size) : 0; + } + return arr; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_source_file(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_begin(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_end(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + int32_t default_val = (int32_t)0; + int32_t ret; + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_clear_semantic(google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_semantic(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + int32_t default_val = 0; + int32_t ret; + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_semantic(const google_protobuf_GeneratedCodeInfo_Annotation* msg) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, + size_t* size) { + upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetMutableArray(UPB_UPCAST(msg), &field); + if (arr) { + if (size) *size = arr->UPB_PRIVATE(size); + return (int32_t*)upb_Array_MutableDataPtr(arr); + } else { + if (size) *size = 0; + return NULL; + } +} + +UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, + size_t size, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + return (int32_t*)upb_Message_ResizeArrayUninitialized( + UPB_UPCAST(msg), &field, size, arena); +} +UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t val, + upb_Arena* arena) { + upb_MiniTableField field = {1, UPB_SIZE(12, 40), 0, kUpb_NoSub, 5, (int)kUpb_FieldMode_Array | (int)kUpb_LabelFlags_IsPacked | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}; + upb_Array* arr = upb_Message_GetOrCreateMutableArray( + UPB_UPCAST(msg), &field, arena); + if (!arr || !UPB_PRIVATE(_upb_Array_ResizeUninitialized)( + arr, arr->UPB_PRIVATE(size) + 1, arena)) { + return false; + } + UPB_PRIVATE(_upb_Array_Set) + (arr, arr->UPB_PRIVATE(size) - 1, &val, sizeof(val)); + return true; +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation* msg, upb_StringView value) { + const upb_MiniTableField field = {2, UPB_SIZE(28, 24), 64, kUpb_NoSub, 12, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsAlternate | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + const upb_MiniTableField field = {3, UPB_SIZE(16, 12), 65, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + const upb_MiniTableField field = {4, UPB_SIZE(20, 16), 66, kUpb_NoSub, 5, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} +UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_semantic(google_protobuf_GeneratedCodeInfo_Annotation* msg, int32_t value) { + const upb_MiniTableField field = {5, UPB_SIZE(24, 20), 67, UPB_SIZE(3, 4), 14, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +/* Max size 32 is google.protobuf.FileOptions */ +/* Max size 64 is google.protobuf.FileOptions */ +#define _UPB_MAXOPT_SIZE UPB_SIZE(112, 200) +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_H_ */ +#endif + +// IWYU pragma: end_exports + +#endif // GOOGLE_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H__ + +// Forward declarations for circular references. +typedef struct upb_DefPool upb_DefPool; +typedef struct upb_EnumDef upb_EnumDef; +typedef struct upb_EnumReservedRange upb_EnumReservedRange; +typedef struct upb_EnumValueDef upb_EnumValueDef; +typedef struct upb_ExtensionRange upb_ExtensionRange; +typedef struct upb_FieldDef upb_FieldDef; +typedef struct upb_FileDef upb_FileDef; +typedef struct upb_MessageDef upb_MessageDef; +typedef struct upb_MessageReservedRange upb_MessageReservedRange; +typedef struct upb_MethodDef upb_MethodDef; +typedef struct upb_OneofDef upb_OneofDef; +typedef struct upb_ServiceDef upb_ServiceDef; + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +typedef struct upb_DefBuilder upb_DefBuilder; + +#endif /* UPB_REFLECTION_COMMON_H_ */ + +#ifndef UPB_REFLECTION_DEF_TYPE_H_ +#define UPB_REFLECTION_DEF_TYPE_H_ + + +// Must be last. + +// Inside a symtab we store tagged pointers to specific def types. +typedef enum { + UPB_DEFTYPE_MASK = 7, + + // Only inside symtab table. + UPB_DEFTYPE_EXT = 0, + UPB_DEFTYPE_MSG = 1, + UPB_DEFTYPE_ENUM = 2, + UPB_DEFTYPE_ENUMVAL = 3, + UPB_DEFTYPE_SERVICE = 4, + + // Only inside message table. + UPB_DEFTYPE_FIELD = 0, + UPB_DEFTYPE_ONEOF = 1, + + // Only inside service table. + UPB_DEFTYPE_METHOD = 0, +} upb_deftype_t; + +#ifdef __cplusplus +extern "C" { +#endif + +// Our 3-bit pointer tagging requires all pointers to be multiples of 8. +// The arena will always yield 8-byte-aligned addresses, however we put +// the defs into arrays. For each element in the array to be 8-byte-aligned, +// the sizes of each def type must also be a multiple of 8. +// +// If any of these asserts fail, we need to add or remove padding on 32-bit +// machines (64-bit machines will have 8-byte alignment already due to +// pointers, which all of these structs have). +UPB_INLINE void _upb_DefType_CheckPadding(size_t size) { + UPB_ASSERT((size & UPB_DEFTYPE_MASK) == 0); +} + +upb_deftype_t _upb_DefType_Type(upb_value v); + +upb_value _upb_DefType_Pack(const void* ptr, upb_deftype_t type); + +const void* _upb_DefType_Unpack(upb_value v, upb_deftype_t type); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_TYPE_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API void upb_DefPool_Free(upb_DefPool* s); + +UPB_API upb_DefPool* upb_DefPool_New(void); + +UPB_API const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults( + const upb_DefPool* s); + +UPB_API bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status); + +UPB_API const upb_MessageDef* upb_DefPool_FindMessageByName( + const upb_DefPool* s, const char* sym); + +const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); + +UPB_API const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, + const char* sym); + +UPB_API const upb_EnumDef* upb_DefPool_FindEnumByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); + +UPB_API const upb_EnumValueDef* upb_DefPool_FindEnumValueByName( + const upb_DefPool* s, const char* sym); + +UPB_API const upb_EnumValueDef* upb_DefPool_FindEnumValueByNameWithSize( + const upb_DefPool* s, const char* sym, size_t len); + +UPB_API const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, + const char* name); + +const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, + const char* name, + size_t len); + +const upb_FieldDef* upb_DefPool_FindExtensionByMiniTable( + const upb_DefPool* s, const upb_MiniTableExtension* ext); + +UPB_API const upb_FieldDef* upb_DefPool_FindExtensionByName( + const upb_DefPool* s, const char* sym); + +const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( + const upb_DefPool* s, const char* name, size_t size); + +const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, + const upb_MessageDef* m, + int32_t fieldnum); + +UPB_API const upb_ServiceDef* upb_DefPool_FindServiceByName( + const upb_DefPool* s, const char* name); + +const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( + const upb_DefPool* s, const char* name, size_t size); + +const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, + const char* name); + +UPB_API const upb_FileDef* upb_DefPool_AddFile( + upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, + upb_Status* status); + +UPB_API const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( + const upb_DefPool* s); + +const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, + const upb_MessageDef* m, + size_t* count); + +// If called, closed enums will be treated as open enums. This is non-standard +// behavior and will cause conformance tests to fail, but it is more useful +// behavior overall and can be used in situations where where the +// non-conformance is acceptable. +// +// This function may only be called immediately after upb_DefPool_New(). +// It is an error to call it on an existing def pool or after defs have +// already been added to the pool. +// +// Note: we still require that implicit presence fields have zero as their +// default value. +UPB_API void upb_DefPool_DisableClosedEnumChecking(upb_DefPool* s); +bool upb_DefPool_ClosedEnumCheckingDisabled(const upb_DefPool* s); + +// If called, implicit field presence will be disabled. +// This is non-standard behavior and will cause conformance tests to fail, but +// it can be used in situations where where the non-conformance is acceptable. +// +// This function may only be called immediately after upb_DefPool_New(). +// It is an error to call it on an existing def pool or after defs have +// already been added to the pool. +UPB_API void upb_DefPool_DisableImplicitFieldPresence(upb_DefPool* s); +bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_POOL_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ENUM_DEF_H_ +#define UPB_REFLECTION_ENUM_DEF_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); +const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); +int32_t upb_EnumDef_Default(const upb_EnumDef* e); +UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e); +const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, + const char* name); +UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( + const upb_EnumDef* e, const char* name, size_t size); +UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNumber( + const upb_EnumDef* e, int32_t num); +UPB_API const char* upb_EnumDef_FullName(const upb_EnumDef* e); +bool upb_EnumDef_HasOptions(const upb_EnumDef* e); +bool upb_EnumDef_IsClosed(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 google_protobuf_FeatureSet* upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e); +google_protobuf_SymbolVisibility upb_EnumDef_Visibility(const upb_EnumDef* e); + +upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i); +int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e); + +const upb_EnumReservedRange* upb_EnumDef_ReservedRange(const upb_EnumDef* e, + int i); +int upb_EnumDef_ReservedRangeCount(const upb_EnumDef* e); + +UPB_API const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i); +UPB_API int upb_EnumDef_ValueCount(const upb_EnumDef* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_ +#define UPB_REFLECTION_ENUM_VALUE_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v); +const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v); +bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v); +uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v); +UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); +UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); +const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( + const upb_EnumValueDef* v); +const google_protobuf_FeatureSet* upb_EnumValueDef_ResolvedFeatures( + const upb_EnumValueDef* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_VALUE_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_EXTENSION_RANGE_H_ +#define UPB_REFLECTION_EXTENSION_RANGE_H_ + +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r); +int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); + +bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); +const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( + const upb_ExtensionRange* r); +const google_protobuf_FeatureSet* upb_ExtensionRange_ResolvedFeatures( + const upb_ExtensionRange* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_EXTENSION_RANGE_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_FIELD_DEF_H_ +#define UPB_REFLECTION_FIELD_DEF_H_ + +#include <stdint.h> + + +// Must be last. + +// Maximum field number allowed for FieldDefs. +// This is an inherent limit of the protobuf wire format. +#define kUpb_MaxFieldNumber ((1 << 29) - 1) + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f); +UPB_API const upb_MessageDef* upb_FieldDef_ContainingType( + const upb_FieldDef* f); +UPB_API upb_CType upb_FieldDef_CType(const upb_FieldDef* f); +UPB_API upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f); +UPB_API const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f); +const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f); +UPB_API const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f); +const char* upb_FieldDef_FullName(const upb_FieldDef* f); +bool upb_FieldDef_HasDefault(const upb_FieldDef* f); +bool upb_FieldDef_HasJsonName(const upb_FieldDef* f); +bool upb_FieldDef_HasOptions(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_HasPresence(const upb_FieldDef* f); +bool upb_FieldDef_HasSubDef(const upb_FieldDef* f); +uint32_t upb_FieldDef_Index(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsEnum(const upb_FieldDef* f); +bool upb_FieldDef_IsExtension(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsMap(const upb_FieldDef* f); +bool upb_FieldDef_IsOptional(const upb_FieldDef* f); +bool _upb_FieldDef_IsPackable(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsPacked(const upb_FieldDef* f); +bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsRepeated(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsRequired(const upb_FieldDef* f); +bool upb_FieldDef_IsString(const upb_FieldDef* f); +UPB_API bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f); +UPB_API const char* upb_FieldDef_JsonName(const upb_FieldDef* f); +UPB_API upb_Label upb_FieldDef_Label(const upb_FieldDef* f); +uint32_t upb_FieldDef_LayoutIndex(const upb_FieldDef* f); +UPB_API const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f); +bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f); +bool _upb_FieldDef_IsGroupLike(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_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f); +const upb_MiniTableExtension* upb_FieldDef_MiniTableExtension( + const upb_FieldDef* f); +UPB_API const char* upb_FieldDef_Name(const upb_FieldDef* f); +UPB_API uint32_t upb_FieldDef_Number(const upb_FieldDef* f); +const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f); +const google_protobuf_FeatureSet* upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f); +UPB_API const upb_OneofDef* upb_FieldDef_RealContainingOneof( + const upb_FieldDef* f); +UPB_API upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FIELD_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_FILE_DEF_H_ +#define UPB_REFLECTION_FILE_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const char* upb_FileDef_EditionName(int edition); + +const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); +int upb_FileDef_DependencyCount(const upb_FileDef* f); +bool upb_FileDef_HasOptions(const upb_FileDef* f); +UPB_API const char* upb_FileDef_Name(const upb_FileDef* f); +const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); +const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f); +const char* upb_FileDef_Package(const upb_FileDef* f); +google_protobuf_Edition upb_FileDef_Edition(const upb_FileDef* f); +UPB_API const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); + +const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i); +int upb_FileDef_PublicDependencyCount(const upb_FileDef* f); + +const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i); +int upb_FileDef_ServiceCount(const upb_FileDef* f); + +const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i); +int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f); + +const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i); +int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f); + +const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i); +int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f); + +const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i); +int upb_FileDef_WeakDependencyCount(const upb_FileDef* f); + +// Returns whether |symbol| is transitively included by |f| +bool upb_FileDef_Resolves(const upb_FileDef* f, const char* symbol); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FILE_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_MESSAGE_DEF_H_ +#define UPB_REFLECTION_MESSAGE_DEF_H_ + + +// Must be last. + +// Well-known field tag numbers for map-entry messages. +#define kUpb_MapEntry_KeyFieldNumber 1 +#define kUpb_MapEntry_ValueFieldNumber 2 + +// Well-known field tag numbers for Any messages. +#define kUpb_Any_TypeFieldNumber 1 +#define kUpb_Any_ValueFieldNumber 2 + +// Well-known field tag numbers for duration messages. +#define kUpb_Duration_SecondsFieldNumber 1 +#define kUpb_Duration_NanosFieldNumber 2 + +// Well-known field tag numbers for timestamp messages. +#define kUpb_Timestamp_SecondsFieldNumber 1 +#define kUpb_Timestamp_NanosFieldNumber 2 + +// All the different kind of well known type messages. For simplicity of check, +// number wrappers and string wrappers are grouped together. Make sure the +// order and number of these groups are not changed. +typedef enum { + kUpb_WellKnown_Unspecified, + kUpb_WellKnown_Any, + kUpb_WellKnown_FieldMask, + kUpb_WellKnown_Duration, + kUpb_WellKnown_Timestamp, + + // number wrappers + kUpb_WellKnown_DoubleValue, + kUpb_WellKnown_FloatValue, + kUpb_WellKnown_Int64Value, + kUpb_WellKnown_UInt64Value, + kUpb_WellKnown_Int32Value, + kUpb_WellKnown_UInt32Value, + + // string wrappers + kUpb_WellKnown_StringValue, + kUpb_WellKnown_BytesValue, + kUpb_WellKnown_BoolValue, + kUpb_WellKnown_Value, + kUpb_WellKnown_ListValue, + kUpb_WellKnown_Struct, +} upb_WellKnown; + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m); + +const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, + int i); +int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m); + +UPB_API const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, + int i); +UPB_API int upb_MessageDef_FieldCount(const upb_MessageDef* m); + +UPB_API const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m); + +// Returns a field by either JSON name or regular proto name. +const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( + const upb_MessageDef* m, const char* name, size_t size); +UPB_INLINE const upb_FieldDef* upb_MessageDef_FindByJsonName( + const upb_MessageDef* m, const char* name) { + return upb_MessageDef_FindByJsonNameWithSize(m, name, strlen(name)); +} + +// Lookup of either field or oneof by name. Returns whether either was found. +// If the return is true, then the found def will be set, and the non-found +// one set to NULL. +UPB_API bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, + const char* name, size_t size, + const upb_FieldDef** f, + const upb_OneofDef** o); +UPB_INLINE bool upb_MessageDef_FindByName(const upb_MessageDef* m, + const char* name, + const upb_FieldDef** f, + const upb_OneofDef** o) { + return upb_MessageDef_FindByNameWithSize(m, name, strlen(name), f, o); +} + +const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, + const char* name); +UPB_API const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size); +UPB_API const upb_FieldDef* upb_MessageDef_FindFieldByNumber( + const upb_MessageDef* m, uint32_t i); +const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, + const char* name); +UPB_API const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( + const upb_MessageDef* m, const char* name, size_t size); +UPB_API 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); + +UPB_API const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m); +const char* upb_MessageDef_Name(const upb_MessageDef* m); + +const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i); +const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, + int i); +const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, + int i); + +int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m); +int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m); +int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m); + +UPB_API const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, + int i); +UPB_API int upb_MessageDef_OneofCount(const upb_MessageDef* m); +int upb_MessageDef_RealOneofCount(const upb_MessageDef* m); + +const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m); +const google_protobuf_FeatureSet* upb_MessageDef_ResolvedFeatures( + const upb_MessageDef* m); + +upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i); +int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m); + +const upb_MessageReservedRange* upb_MessageDef_ReservedRange( + const upb_MessageDef* m, int i); +int upb_MessageDef_ReservedRangeCount(const upb_MessageDef* m); + +UPB_API upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m); +UPB_API google_protobuf_SymbolVisibility +upb_MessageDef_Visibility(const upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_METHOD_DEF_H_ +#define UPB_REFLECTION_METHOD_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m); +const char* upb_MethodDef_FullName(const upb_MethodDef* m); +bool upb_MethodDef_HasOptions(const upb_MethodDef* m); +int upb_MethodDef_Index(const upb_MethodDef* m); +UPB_API const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); +UPB_API const char* upb_MethodDef_Name(const upb_MethodDef* m); +UPB_API const google_protobuf_MethodOptions* upb_MethodDef_Options( + const upb_MethodDef* m); +const google_protobuf_FeatureSet* upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m); +UPB_API const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); +UPB_API bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); +UPB_API const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_METHOD_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ONEOF_DEF_H_ +#define UPB_REFLECTION_ONEOF_DEF_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const upb_MessageDef* upb_OneofDef_ContainingType( + const upb_OneofDef* o); +UPB_API const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i); +UPB_API int upb_OneofDef_FieldCount(const upb_OneofDef* o); +const char* upb_OneofDef_FullName(const upb_OneofDef* o); +bool upb_OneofDef_HasOptions(const upb_OneofDef* o); +uint32_t upb_OneofDef_Index(const upb_OneofDef* o); +bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o); +const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, + const char* name); +const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, + const char* name, + size_t size); +const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, + uint32_t num); +UPB_API const char* upb_OneofDef_Name(const upb_OneofDef* o); +int upb_OneofDef_numfields(const upb_OneofDef* o); +const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o); +const google_protobuf_FeatureSet* upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ONEOF_DEF_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_SERVICE_DEF_H_ +#define UPB_REFLECTION_SERVICE_DEF_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s); +const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, + const char* name); +const upb_MethodDef* upb_ServiceDef_FindMethodByNameWithSize( + const upb_ServiceDef* s, const char* name, size_t len); +UPB_API const char* upb_ServiceDef_FullName(const upb_ServiceDef* s); +bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s); +int upb_ServiceDef_Index(const upb_ServiceDef* s); +UPB_API const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, + int i); +UPB_API int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); +const char* upb_ServiceDef_Name(const upb_ServiceDef* s); +UPB_API const google_protobuf_ServiceOptions* upb_ServiceDef_Options( + const upb_ServiceDef* s); +const google_protobuf_FeatureSet* upb_ServiceDef_ResolvedFeatures( + const upb_ServiceDef* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_SERVICE_DEF_H_ */ +// IWYU pragma: end_exports + +#endif /* UPB_REFLECTION_DEF_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +enum { upb_JsonDecode_IgnoreUnknown = 1 }; + +enum { + kUpb_JsonDecodeResult_Ok = 0, + kUpb_JsonDecodeResult_Error = 2, +}; + +UPB_API int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size, + upb_Message* msg, + const upb_MessageDef* m, + const upb_DefPool* symtab, + int options, upb_Arena* arena, + upb_Status* status); + +UPB_API_INLINE bool upb_JsonDecode(const char* buf, size_t size, + upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* symtab, int options, + upb_Arena* arena, upb_Status* status) { + return upb_JsonDecodeDetectingNonconformance(buf, size, msg, m, symtab, + options, arena, status) == + kUpb_JsonDecodeResult_Ok; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_JSONDECODE_H_ */ + +#ifndef UPB_LEX_ATOI_H_ +#define UPB_LEX_ATOI_H_ + +#include <stdint.h> + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// We use these hand-written routines instead of strto[u]l() because the "long +// long" variants aren't in c89. Also our version allows setting a ptr limit. +// Return the new position of the pointer after parsing the int, or NULL on +// integer overflow. + +const char* upb_BufToUint64(const char* ptr, const char* end, uint64_t* val); +const char* upb_BufToInt64(const char* ptr, const char* end, int64_t* val, + bool* is_neg); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_ATOI_H_ */ + +#ifndef UPB_LEX_UNICODE_H_ +#define UPB_LEX_UNICODE_H_ + +#include <stdint.h> + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns true iff a codepoint is the value for a high surrogate. +UPB_INLINE bool upb_Unicode_IsHigh(uint32_t cp) { + return (cp >= 0xd800 && cp <= 0xdbff); +} + +// Returns true iff a codepoint is the value for a low surrogate. +UPB_INLINE bool upb_Unicode_IsLow(uint32_t cp) { + return (cp >= 0xdc00 && cp <= 0xdfff); +} + +// Returns the high 16-bit surrogate value for a supplementary codepoint. +// Does not sanity-check the input. +UPB_INLINE uint16_t upb_Unicode_ToHigh(uint32_t cp) { + return (cp >> 10) + 0xd7c0; +} + +// Returns the low 16-bit surrogate value for a supplementary codepoint. +// Does not sanity-check the input. +UPB_INLINE uint16_t upb_Unicode_ToLow(uint32_t cp) { + return (cp & 0x3ff) | 0xdc00; +} + +// Returns the 32-bit value corresponding to a pair of 16-bit surrogates. +// Does not sanity-check the input. +UPB_INLINE uint32_t upb_Unicode_FromPair(uint32_t high, uint32_t low) { + return ((high & 0x3ff) << 10) + (low & 0x3ff) + 0x10000; +} + +// Outputs a codepoint as UTF8. +// Returns the number of bytes written (1-4 on success, 0 on error). +// Does not sanity-check the input. Specifically does not check for surrogates. +int upb_Unicode_ToUTF8(uint32_t cp, char* out); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_UNICODE_H_ */ + +#ifndef UPB_REFLECTION_MESSAGE_H_ +#define UPB_REFLECTION_MESSAGE_H_ + +#include <stddef.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns a mutable pointer to a map, array, or submessage value. If the given +// arena is non-NULL this will construct a new object if it was not previously +// present. May not be called for primitive fields. +UPB_API upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, + const upb_FieldDef* f, + upb_Arena* a); + +// Returns the field that is set in the oneof, or NULL if none are set. +UPB_API const upb_FieldDef* upb_Message_WhichOneofByDef(const upb_Message* msg, + const upb_OneofDef* o); + +// Clear all data and unknown fields. +void upb_Message_ClearByDef(upb_Message* msg, const upb_MessageDef* m); + +// Clears any field presence and sets the value back to its default. +UPB_API void upb_Message_ClearFieldByDef(upb_Message* msg, + const upb_FieldDef* f); + +// May only be called for fields where upb_FieldDef_HasPresence(f) == true. +UPB_API bool upb_Message_HasFieldByDef(const upb_Message* msg, + const upb_FieldDef* f); + +// Returns the value in the message associated with this field def. +UPB_API upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, + const upb_FieldDef* f); + +// Sets the given field to the given value. For a msg/array/map/string, the +// caller must ensure that the target data outlives |msg| (by living either in +// the same arena or a different arena that outlives it). +// +// Returns false if allocation fails. +UPB_API bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, + upb_MessageValue val, upb_Arena* a); + +// Iterate over present fields. +// +// size_t iter = kUpb_Message_Begin; +// const upb_FieldDef *f; +// upb_MessageValue val; +// while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { +// process_field(f, val); +// } +// +// If ext_pool is NULL, no extensions will be returned. If the given symtab +// returns extensions that don't match what is in this message, those extensions +// will be skipped. + +#define kUpb_Message_Begin -1 + +UPB_API bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, + const upb_FieldDef** f, upb_MessageValue* val, + size_t* iter); + +// Clears all unknown field data from this message and all submessages. +UPB_API bool upb_Message_DiscardUnknown(upb_Message* msg, + const upb_MessageDef* m, + const upb_DefPool* ext_pool, + int maxdepth); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_H_ */ + +#ifndef UPB_JSON_ENCODE_H_ +#define UPB_JSON_ENCODE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + /* When set, emits 0/default values. TODO: proto3 only? */ + upb_JsonEncode_EmitDefaults = 1 << 0, + + /* When set, use normal (snake_case) field names instead of JSON (camelCase) + names. */ + upb_JsonEncode_UseProtoNames = 1 << 1, + + /* When set, emits enums as their integer values instead of as their names. */ + upb_JsonEncode_FormatEnumsAsIntegers = 1 << 2 +}; + +/* Encodes the given |msg| to JSON format. The message's reflection is given in + * |m|. The DefPool in |ext_pool| is used to find extensions (if NULL, + * extensions will not be printed). + * + * Output is placed in the given buffer, and always NULL-terminated. The output + * size (excluding NULL) is returned. This means that a return value >= |size| + * implies that the output was truncated. (These are the same semantics as + * snprintf()). */ +UPB_API size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m, + const upb_DefPool* ext_pool, int options, + char* buf, size_t size, upb_Status* status); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_JSONENCODE_H_ */ + +#ifndef UPB_LEX_ROUND_TRIP_H_ +#define UPB_LEX_ROUND_TRIP_H_ + +// Must be last. + +// Encodes a float or double that is round-trippable, but as short as possible. +// These routines are not fully optimal (not guaranteed to be shortest), but are +// short-ish and match the implementation that has been used in protobuf since +// the beginning. + +// The given buffer size must be at least kUpb_RoundTripBufferSize. +enum { kUpb_RoundTripBufferSize = 32 }; + +#ifdef __cplusplus +extern "C" { +#endif + +void _upb_EncodeRoundTripDouble(double val, char* buf, size_t size); +void _upb_EncodeRoundTripFloat(float val, char* buf, size_t size); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_ROUND_TRIP_H_ */ + +#ifndef UPB_PORT_VSNPRINTF_COMPAT_H_ +#define UPB_PORT_VSNPRINTF_COMPAT_H_ + +// Must be last. + +UPB_INLINE int _upb_vsnprintf(char* buf, size_t size, const char* fmt, + va_list ap) { +#if defined(__MINGW64__) || defined(__MINGW32__) || defined(_MSC_VER) + // The msvc runtime has a non-conforming vsnprintf() that requires the + // following compatibility code to become conformant. + int n = -1; + if (size != 0) n = _vsnprintf_s(buf, size, _TRUNCATE, fmt, ap); + if (n == -1) n = _vscprintf(fmt, ap); + return n; +#else + return vsnprintf(buf, size, fmt, ap); +#endif +} + + +#endif // UPB_PORT_VSNPRINTF_COMPAT_H_ + +#ifndef UPB_LEX_STRTOD_H_ +#define UPB_LEX_STRTOD_H_ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +double _upb_NoLocaleStrtod(const char *str, char **endptr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_LEX_STRTOD_H_ */ + +#ifndef UPB_PORT_ATOMIC_H_ +#define UPB_PORT_ATOMIC_H_ + + +#ifdef UPB_USE_C11_ATOMICS + +// IWYU pragma: begin_exports +#include <stdatomic.h> +#include <stdbool.h> +// IWYU pragma: end_exports + +#define upb_Atomic_Init(addr, val) atomic_init(addr, val) +#define upb_Atomic_Load(addr, order) atomic_load_explicit(addr, order) +#define upb_Atomic_Store(addr, val, order) \ + atomic_store_explicit(addr, val, order) +#define upb_Atomic_Exchange(addr, val, order) \ + atomic_exchange_explicit(addr, val, order) +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + atomic_compare_exchange_strong_explicit(addr, expected, desired, \ + success_order, failure_order) +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + atomic_compare_exchange_weak_explicit(addr, expected, desired, \ + success_order, failure_order) +#define upb_Atomic_Add(addr, val, order) \ + atomic_fetch_add_explicit(addr, val, order) +#define upb_Atomic_Sub(addr, val, order) \ + atomic_fetch_sub_explicit(addr, val, order) + +#elif defined(UPB_USE_MSC_ATOMICS) +#include <intrin.h> +#include <stdbool.h> +#include <stdint.h> + +#define upb_Atomic_Init(addr, val) (*(addr) = val) + +#pragma intrinsic(_InterlockedExchange) +static int32_t upb_Atomic_LoadMsc32(int32_t volatile* addr) { + // Compare exchange with an unlikely value reduces the risk of a spurious + // (but harmless) store + return _InterlockedCompareExchange(addr, 0xDEADC0DE, 0xDEADC0DE); +} + +#pragma intrinsic(_InterlockedCompareExchange) +static bool upb_Atomic_CompareExchangeMscP32(int32_t volatile* addr, + int32_t* expected, + int32_t desired) { + int32_t expect_val = *expected; + int32_t actual_val = _InterlockedCompareExchange(addr, desired, expect_val); + if (expect_val != actual_val) { + *expected = actual_val; + return false; + } + return true; +} + +#if defined(_WIN64) +// MSVC, without C11 atomics, does not have any way in pure C to force +// load-acquire store-release behavior, so we hack it with exchanges. +#pragma intrinsic(_InterlockedCompareExchange64) +static uintptr_t upb_Atomic_LoadMsc64(uint64_t volatile* addr) { + // Compare exchange with an unlikely value reduces the risk of a spurious + // (but harmless) store + return _InterlockedCompareExchange64(addr, 0xDEADC0DEBAADF00D, + 0xDEADC0DEBAADF00D); +} + +#pragma intrinsic(_InterlockedCompareExchange64) +static bool upb_Atomic_CompareExchangeMscP64(uint64_t volatile* addr, + uint64_t* expected, + uint64_t desired) { + uint64_t expect_val = *expected; + uint64_t actual_val = + _InterlockedCompareExchange64(addr, desired, expect_val); + if (expect_val != actual_val) { + *expected = actual_val; + return false; + } + return true; +} + +#pragma intrinsic(_InterlockedExchange64) +// If _Generic is available, use it to avoid emitting a "'uintptr_t' differs in +// levels of indirection from 'void *'" or -Wint-conversion compiler warning. +#if __STDC_VERSION__ >= 201112L +#define upb_Atomic_Store(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: (void)_InterlockedExchange64( \ + (uint64_t volatile*)(addr), (uint64_t)val), \ + UPB_ATOMIC(int32_t)*: (void)_InterlockedExchange( \ + (int32_t volatile*)(addr), (int32_t)val), \ + default: (void)_InterlockedExchange64((uint64_t volatile*)addr, \ + (uint64_t)val)) + +#define upb_Atomic_Load(addr, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: upb_Atomic_LoadMsc64( \ + (uint64_t volatile*)(addr)), \ + UPB_ATOMIC(int32_t)*: upb_Atomic_LoadMsc32((int32_t volatile*)(addr)), \ + default: (void*)upb_Atomic_LoadMsc64((uint64_t volatile*)(addr))) + +#define upb_Atomic_Exchange(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: _InterlockedExchange64( \ + (uint64_t volatile*)(addr), (uint64_t)val), \ + UPB_ATOMIC(int32_t)*: _InterlockedExchange((int32_t volatile*)(addr), \ + (int32_t)val), \ + default: (void*)_InterlockedExchange64((uint64_t volatile*)addr, \ + (uint64_t)val)) + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + _Generic(addr, \ + UPB_ATOMIC(int32_t)*: upb_Atomic_CompareExchangeMscP32( \ + (int32_t volatile*)(addr), (int32_t*)expected, \ + (int32_t)desired), \ + default: upb_Atomic_CompareExchangeMscP64((uint64_t volatile*)(addr), \ + (uint64_t*)expected, \ + (uint64_t)desired)) + +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + _Generic(addr, \ + UPB_ATOMIC(int32_t)*: upb_Atomic_CompareExchangeMscP32( \ + (int32_t volatile*)(addr), (int32_t*)expected, \ + (int32_t)desired), \ + default: upb_Atomic_CompareExchangeMscP64((uint64_t volatile*)(addr), \ + (uint64_t*)expected, \ + (uint64_t)desired)) + +#else + +UPB_INLINE void _upb_Atomic_StoreP(void volatile* addr, uint64_t val, + size_t size) { + if (size == sizeof(int32_t)) { + (void)_InterlockedExchange((int32_t volatile*)addr, (int32_t)val); + } else { + (void)_InterlockedExchange64((uint64_t volatile*)addr, val); + } +} + +#define upb_Atomic_Store(addr, val, order) \ + _upb_Atomic_StoreP(addr, val, sizeof(*addr)) + +UPB_INLINE int64_t _upb_Atomic_LoadP(void volatile* addr, size_t size) { + if (size == sizeof(int32_t)) { + return (int64_t)upb_Atomic_LoadMsc32((int32_t volatile*)addr); + } else { + return upb_Atomic_LoadMsc64((uint64_t volatile*)addr); + } +} + +#define upb_Atomic_Load(addr, order) \ + (void*)_upb_Atomic_LoadP((void volatile*)addr, sizeof(*addr)) + +UPB_INLINE int64_t _upb_Atomic_ExchangeP(void volatile* addr, uint64_t val, + size_t size) { + if (size == sizeof(int32_t)) { + return (int64_t)_InterlockedExchange((int32_t volatile*)addr, (int32_t)val); + } else { + return (int64_t)_InterlockedExchange64((uint64_t volatile*)addr, val); + } +} + +#define upb_Atomic_Exchange(addr, val, order) \ + (void*)_upb_Atomic_ExchangeP((void volatile*)addr, (uint64_t)val, \ + sizeof(*addr)) + +UPB_INLINE bool _upb_Atomic_CompareExchangeMscP(void volatile* addr, + void* expected, + uint64_t desired, size_t size) { + if (size == sizeof(int32_t)) { + return upb_Atomic_CompareExchangeMscP32( + (int32_t volatile*)addr, (int32_t*)expected, (int32_t)desired); + } else { + return upb_Atomic_CompareExchangeMscP64((uint64_t volatile*)addr, + (uint64_t*)expected, desired); + } +} + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + _upb_Atomic_CompareExchangeMscP(addr, expected, (uint64_t)desired, \ + sizeof(*addr)) + +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + _upb_Atomic_CompareExchangeMscP(addr, expected, (uint64_t)desired, \ + sizeof(*addr)) + +#endif + +#else // 32 bit pointers +#pragma intrinsic(_InterlockedExchange) +#define upb_Atomic_Store(addr, val, order) \ + (void)_InterlockedExchange((uint32_t volatile*)addr, (uint32_t)val) + +// If _Generic is available, use it to avoid emitting 'uintptr_t' differs in +// levels of indirection from 'void *' +#if __STDC_VERSION__ >= 201112L +#define upb_Atomic_Load(addr, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: (uintptr_t)upb_Atomic_LoadMsc32( \ + (uint32_t volatile*)(addr)), \ + UPB_ATOMIC(int32_t)*: upb_Atomic_LoadMsc32((int32_t volatile*)(addr)), \ + default: (void*)upb_Atomic_LoadMsc32((uint32_t volatile*)(addr))) + +#define upb_Atomic_Exchange(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(uintptr_t)*: _InterlockedExchange((uint32_t volatile*)(addr), \ + (uint32_t)val), \ + default: (void*)_InterlockedExchange((uint32_t volatile*)addr, \ + (uint32_t)val)) +#else +#define upb_Atomic_Load(addr, order) \ + (void*)upb_Atomic_LoadMsc32((uint32_t volatile*)(addr)) + +#define upb_Atomic_Exchange(addr, val, order) \ + (void*)_InterlockedExchange((uint32_t volatile*)addr, (uint32_t)val) +#endif + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + upb_Atomic_CompareExchangeMscP32((uint32_t volatile*)addr, \ + (uint32_t*)expected, (uint32_t)desired) + +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + upb_Atomic_CompareExchangeMscP32((uint32_t volatile*)addr, \ + (uint32_t*)expected, (uint32_t)desired) +#endif + +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedExchangeAdd64) + +// If _Generic is available, use it to switch between 32 and 64 bit types. +#if __STDC_VERSION__ >= 201112L +#define upb_Atomic_Add(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(int64_t)*: _InterlockedExchangeAdd64(addr, (int64_t)val), \ + UPB_ATOMIC(int32_t)*: _InterlockedExchangeAdd(addr, (int32_t)val)) +#define upb_Atomic_Sub(addr, val, order) \ + _Generic(addr, \ + UPB_ATOMIC(int64_t)*: _InterlockedExchangeAdd64(addr, -(int64_t)val), \ + UPB_ATOMIC(int32_t)*: _InterlockedExchangeAdd(addr, -(int32_t)val)) +#else +#define upb_Atomic_Add(addr, val, order) \ + sizeof(*addr) == sizeof(int32_t) \ + ? _InterlockedExchangeAdd((uint32_t volatile*)addr, (int32_t)val) \ + : _InterlockedExchangeAdd64((uint64_t volatile*)addr, (int64_t)val) +#define upb_Atomic_Sub(addr, val, order) \ + sizeof(*addr) == sizeof(int32_t) \ + ? _InterlockedExchangeAdd((uint32_t volatile*)addr, -(int32_t)val) \ + : _InterlockedExchangeAdd64((uint64_t volatile*)addr, -(int64_t)val) +#endif + +#else // No atomics + +#if !defined(UPB_SUPPRESS_MISSING_ATOMICS) +// NOLINTNEXTLINE +#error Your compiler does not support atomic instructions, which UPB uses. If you do not use UPB on multiple threads, you can suppress this error by defining UPB_SUPPRESS_MISSING_ATOMICS. +#endif + +#include <string.h> + +#define upb_Atomic_Init(addr, val) (*addr = val) +#define upb_Atomic_Load(addr, order) (*addr) +#define upb_Atomic_Store(addr, val, order) (*(addr) = val) + +UPB_INLINE void* _upb_NonAtomic_Exchange(void* addr, void* value) { + void* old; + memcpy(&old, addr, sizeof(value)); + memcpy(addr, &value, sizeof(value)); + return old; +} + +#define upb_Atomic_Exchange(addr, val, order) _upb_NonAtomic_Exchange(addr, val) + +// `addr` and `expected` are logically double pointers. +UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, + void* expected, + void* desired) { + if (memcmp(addr, expected, sizeof(desired)) == 0) { + memcpy(addr, &desired, sizeof(desired)); + return true; + } else { + memcpy(expected, addr, sizeof(desired)); + return false; + } +} + +#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \ + success_order, failure_order) \ + _upb_NonAtomic_CompareExchangeStrongP((void*)addr, (void*)expected, \ + (void*)desired) +#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \ + failure_order) \ + upb_Atomic_CompareExchangeStrong(addr, expected, desired, 0, 0) + +#define upb_Atomic_Add(addr, val, order) (*addr += val) +#define upb_Atomic_Sub(addr, val, order) (*addr -= val) + +#endif + + +#endif // UPB_PORT_ATOMIC_H_ + +#ifndef UPB_MESSAGE_COMPAT_H_ +#define UPB_MESSAGE_COMPAT_H_ + +#include <stdint.h> + + +// Must be last. + +// upb does not support mixing minitables from different sources but these +// functions are still used by some existing users so for now we make them +// available here. This may or may not change in the future so do not add +// them to new code. + +#ifdef __cplusplus +extern "C" { +#endif + +// Same as upb_Message_NextExtension but iterates in reverse wire order +bool upb_Message_NextExtensionReverse(const upb_Message* msg, + const upb_MiniTableExtension** result, + uintptr_t* iter); +// Returns the minitable with the given field number, or NULL on failure. +const upb_MiniTableExtension* upb_Message_FindExtensionByNumber( + const upb_Message* msg, uint32_t field_number); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_COMPAT_H_ */ + +// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// + +#ifndef UPB_MESSAGE_INTERNAL_MAP_SORTER_H_ +#define UPB_MESSAGE_INTERNAL_MAP_SORTER_H_ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + + +#ifndef UPB_MESSAGE_INTERNAL_MAP_ENTRY_H_ +#define UPB_MESSAGE_INTERNAL_MAP_ENTRY_H_ + +#include <stdint.h> + + +// Map entries aren't actually stored for map fields, they are only used during +// parsing. (It helps a lot if all map entry messages have the same layout.) +// The mini_table layout code will ensure that all map entries have this layout. +// +// Note that users can and do create map entries directly, which will also use +// this layout. + +typedef struct { + struct upb_Message message; + // We only need 2 hasbits max, but due to alignment we'll use 8 bytes here, + // and the uint64_t helps make this clear. + uint64_t hasbits; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + double d[2]; // Padding for 32-bit builds. + } k; + union { + upb_StringView str; // For str/bytes. + upb_value val; // For all other types. + double d[2]; // Padding for 32-bit builds. + } v; +} upb_MapEntry; + +#endif // UPB_MESSAGE_INTERNAL_MAP_ENTRY_H_ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// _upb_mapsorter sorts maps and provides ordered iteration over the entries. +// Since maps can be recursive (map values can be messages which contain other +// maps), _upb_mapsorter can contain a stack of maps. + +typedef struct { + void const** entries; + int size; + int cap; +} _upb_mapsorter; + +typedef struct { + int start; + int pos; + int end; +} _upb_sortedmap; + +UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) { + s->entries = NULL; + s->size = 0; + s->cap = 0; +} + +UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) { + if (s->entries) upb_gfree(s->entries); +} + +UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, + const struct upb_Map* map, + _upb_sortedmap* sorted, upb_MapEntry* ent) { + if (sorted->pos == sorted->end) return false; + const upb_tabent* tabent = (const upb_tabent*)s->entries[sorted->pos++]; + if (map->UPB_PRIVATE(is_strtable)) { + upb_StringView key = upb_key_strview(tabent->key); + _upb_map_fromkey(key, &ent->k, map->key_size); + } else { + uintptr_t key = tabent->key.num; + memcpy(&ent->k, &key, map->key_size); + } + upb_value val = {tabent->val.val}; + _upb_map_fromvalue(val, &ent->v, map->val_size); + return true; +} + +UPB_INLINE bool _upb_sortedmap_nextext(_upb_mapsorter* s, + _upb_sortedmap* sorted, + const upb_Extension** ext) { + if (sorted->pos == sorted->end) return false; + *ext = (const upb_Extension*)s->entries[sorted->pos++]; + return true; +} + +UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s, + _upb_sortedmap* sorted) { + s->size = sorted->start; +} + +bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, + const struct upb_Map* map, _upb_sortedmap* sorted); + +bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, + _upb_sortedmap* sorted); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_MAP_SORTER_H_ */ + +#ifndef UPB_MESSAGE_COMPARE_H_ +#define UPB_MESSAGE_COMPARE_H_ + +#include <stddef.h> + + +// Must be last. + +enum { + // If set, upb_Message_IsEqual() will attempt to compare unknown fields. + // By its very nature this comparison is inexact. + kUpb_CompareOption_IncludeUnknownFields = (1 << 0) +}; + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns true if no known fields or extensions are set in the message. +UPB_API bool upb_Message_IsEmpty(const upb_Message* msg, + const upb_MiniTable* m); + +UPB_API bool upb_Message_IsEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, int options); + +// If |ctype| is a message then |m| must point to its minitable. +UPB_API_INLINE bool upb_MessageValue_IsEqual(upb_MessageValue val1, + upb_MessageValue val2, + upb_CType ctype, + const upb_MiniTable* m, + int options) { + switch (ctype) { + case kUpb_CType_Bool: + return val1.bool_val == val2.bool_val; + + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return val1.int32_val == val2.int32_val; + + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return val1.int64_val == val2.int64_val; + + case kUpb_CType_String: + case kUpb_CType_Bytes: + return upb_StringView_IsEqual(val1.str_val, val2.str_val); + + case kUpb_CType_Message: + return upb_Message_IsEqual(val1.msg_val, val2.msg_val, m, options); + + default: + UPB_UNREACHABLE(); + return false; + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MESSAGE_COMPARE_H_ + +#ifndef UPB_MESSAGE_INTERNAL_COMPARE_UNKNOWN_H_ +#define UPB_MESSAGE_INTERNAL_COMPARE_UNKNOWN_H_ + +#include <stddef.h> + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns true if unknown fields from the two messages are equal when sorted +// and varints are made canonical. +// +// This function is discouraged, as the comparison is inherently lossy without +// schema data: +// +// 1. We don't know whether delimited fields are sub-messages. Unknown +// sub-messages will therefore not have their fields sorted and varints +// canonicalized. +// 2. We don't know about oneof/non-repeated fields, which should semantically +// discard every value except the last. + +typedef enum { + kUpb_UnknownCompareResult_Equal = 0, + kUpb_UnknownCompareResult_NotEqual = 1, + kUpb_UnknownCompareResult_OutOfMemory = 2, + kUpb_UnknownCompareResult_MaxDepthExceeded = 3, +} upb_UnknownCompareResult; + +upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( + const upb_Message* msg1, const upb_Message* msg2, int max_depth); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MESSAGE_INTERNAL_COMPARE_UNKNOWN_H_ */ + +#ifndef GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ +#define GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#define kUpb_BaseField_Begin ((size_t)-1) +bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg, + const upb_MiniTable* m, + const upb_MiniTableField** out_f, + upb_MessageValue* out_v, + uintptr_t* iter); + +#endif // GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ + +#ifndef UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ +#define UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ + +#include <stddef.h> +#include <stdint.h> + + +#ifndef GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__ +#define GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__ + +#include <setjmp.h> + +// Must be last. + +// upb_ErrorHandler is a standard longjmp()-based exception handler for UPB. +// It is used for efficient error handling in cases where longjmp() is safe to +// use, such as in highly performance-sensitive C parsing code. +// +// This structure contains both a jmp_buf and an error code; the error code is +// stored in the structure prior to calling longjmp(). This is necessary because +// per the C standard, it is not possible to store the result of setjmp(), so +// the error code must be passed out-of-band. +// +// upb_ErrorHandler is generally not C++-compatible, because longjmp() does not +// run C++ destructors. So any library that supports upb_ErrorHandler should +// also support a regular return-based error handling mechanism. (Note: we +// could conceivably extend this to take a callback, which could either call +// longjmp() or throw a C++ exception. But since C++ exceptions are forbidden +// by the C++ style guide, there's not likely to be a demand for this.) +// +// To support both cases (longjmp() or return-based status) efficiently, code +// can be written like this: +// +// UPB_ATTR_CONST bool upb_Arena_HasErrHandler(const upb_Arena* a); +// +// INLINE void* upb_Arena_Malloc(upb_Arena* a, size_t size) { +// if (UPB_UNLIKELY(a->end - a->ptr < size)) { +// void* ret = upb_Arena_MallocFallback(a, size); +// UPB_MAYBE_ASSUME(upb_Arena_HasErrHandler(a), ret != NULL); +// return ret; +// } +// void* ret = a->ptr; +// a->ptr += size; +// UPB_ASSUME(ret != NULL); +// return ret; +// } +// +// If the optimizer can prove that an error handler is present, it can assume +// that upb_Arena_Malloc() will not return NULL. + +// We need to standardize on any error code that might be thrown by an error +// handler. + +typedef enum { + kUpb_ErrorCode_Ok = 0, + kUpb_ErrorCode_OutOfMemory = 1, + kUpb_ErrorCode_Malformed = 2, +} upb_ErrorCode; + +typedef struct { + int code; + jmp_buf buf; +} upb_ErrorHandler; + +UPB_INLINE void upb_ErrorHandler_Init(upb_ErrorHandler* e) { + e->code = kUpb_ErrorCode_Ok; +} + +UPB_INLINE UPB_NORETURN void upb_ErrorHandler_ThrowError(upb_ErrorHandler* e, + int code) { + UPB_ASSERT(code != kUpb_ErrorCode_Ok); + e->code = code; + UPB_LONGJMP(e->buf, 1); +} + + +#endif // GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__ + +#ifndef UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_ +#define UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// The maximum number of bytes a single protobuf field can take up in the +// wire format. We only want to do one bounds check per field, so the input +// stream guarantees that after upb_EpsCopyInputStream_IsDone() is called, +// the decoder can read this many bytes without performing another bounds +// check. The stream will copy into a patch buffer as necessary to guarantee +// this invariant. Since tags can only be up to 5 bytes, and a max-length scalar +// field can be 10 bytes, only 15 is required; but sizing up to 16 permits more +// efficient fixed size copies. +#define kUpb_EpsCopyInputStream_SlopBytes 16 + +struct upb_EpsCopyInputStream { + const char* end; // Can read up to SlopBytes bytes beyond this. + const char* limit_ptr; // For bounds checks, = end + UPB_MIN(limit, 0) + uintptr_t input_delta; // Diff between the original input pointer and patch + const char* buffer_start; // Pointer to the original input buffer + const char* capture_start; // If non-NULL, the start of the captured region. + ptrdiff_t limit; // Submessage limit relative to end + upb_ErrorHandler* err; // Error handler to use when things go wrong. + bool error; // To distinguish between EOF and error. +#ifndef NDEBUG + int guaranteed_bytes; +#endif + // Allocate double the size of what's required; this permits a fixed-size copy + // from the input buffer, regardless of how many bytes actually remain in the + // input buffer. + char patch[kUpb_EpsCopyInputStream_SlopBytes * 2]; +}; + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)( + struct upb_EpsCopyInputStream* e); + +UPB_INLINE bool upb_EpsCopyInputStream_IsError( + struct upb_EpsCopyInputStream* e) { + return e->error; +} + +UPB_INLINE void upb_EpsCopyInputStream_InitWithErrorHandler( + struct upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_ErrorHandler* err) { + e->buffer_start = *ptr; + e->capture_start = NULL; + e->err = err; + if (size <= kUpb_EpsCopyInputStream_SlopBytes) { + memset(&e->patch, 0, 32); + if (size) memcpy(&e->patch, *ptr, size); + e->input_delta = (uintptr_t)*ptr - (uintptr_t)e->patch; + *ptr = e->patch; + e->end = *ptr + size; + e->limit = 0; + } else { + e->end = *ptr + size - kUpb_EpsCopyInputStream_SlopBytes; + e->limit = kUpb_EpsCopyInputStream_SlopBytes; + e->input_delta = 0; + } + e->limit_ptr = e->end; + e->error = false; + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); +} + +UPB_INLINE void upb_EpsCopyInputStream_Init(struct upb_EpsCopyInputStream* e, + const char** ptr, size_t size) { + upb_EpsCopyInputStream_InitWithErrorHandler(e, ptr, size, NULL); +} + +UPB_ATTR_CONST +UPB_INLINE bool upb_EpsCopyInputStream_HasErrorHandler( + const struct upb_EpsCopyInputStream* e) { + return e && e->err != NULL; +} + +// Call this function to signal an error. If an error handler is set, it will be +// called and the function will never return. Otherwise, returns NULL to +// indicate an error. +const char* UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)( + struct upb_EpsCopyInputStream* e); + +UPB_INLINE const char* UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)( + struct upb_EpsCopyInputStream* e, const char* ptr) { + UPB_MAYBE_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(e), ptr != NULL); + return ptr; +} + +//////////////////////////////////////////////////////////////////////////////// + +// Debug checks that attempt to ensure that no code paths will overrun the slop +// bytes even in the worst case. Since we are frequently parsing varints, it's +// possible that the user is trying to parse too many varints before calling +// upb_EpsCopyInputStream_IsDone(), but this error case is not detected because +// the varints are short. These checks ensure that will not overrun the slop +// bytes, even if each varint is its maximum possible length. + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)( + struct upb_EpsCopyInputStream* e) { +#ifndef NDEBUG + e->guaranteed_bytes = kUpb_EpsCopyInputStream_SlopBytes; +#endif +} + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)( + struct upb_EpsCopyInputStream* e) { +#ifndef NDEBUG + e->guaranteed_bytes = 0; +#endif +} + +// Signals the maximum number that the operation about to be performed may +// consume. +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)( + struct upb_EpsCopyInputStream* e, int n) { +#ifndef NDEBUG + if (e) { + UPB_ASSERT(e->guaranteed_bytes >= n); + e->guaranteed_bytes -= n; + } +#endif +} + +//////////////////////////////////////////////////////////////////////////////// + +typedef enum { + // The current stream position is at a limit. + kUpb_IsDoneStatus_Done, + + // The current stream position is not at a limit. + kUpb_IsDoneStatus_NotDone, + + // The current stream position is not at a limit, and the stream needs to + // be flipped to a new buffer before more data can be read. + kUpb_IsDoneStatus_NeedFallback, +} upb_IsDoneStatus; + +// Returns the status of the current stream position. This is a low-level +// function, it is simpler to call upb_EpsCopyInputStream_IsDone() if possible. +UPB_INLINE upb_IsDoneStatus UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneStatus)( + struct upb_EpsCopyInputStream* e, const char* ptr, int* overrun) { + *overrun = ptr - e->end; + if (UPB_LIKELY(ptr < e->limit_ptr)) { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + return kUpb_IsDoneStatus_NotDone; + } else if (UPB_LIKELY(*overrun == e->limit)) { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + return kUpb_IsDoneStatus_Done; + } else { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + return kUpb_IsDoneStatus_NeedFallback; + } +} + +const char* UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)( + struct upb_EpsCopyInputStream* e, const char* ptr, int overrun); + +UPB_INLINE bool upb_EpsCopyInputStream_IsDone(struct upb_EpsCopyInputStream* e, + const char** ptr) { + int overrun; + switch (UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneStatus)(e, *ptr, &overrun)) { + case kUpb_IsDoneStatus_Done: + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + return true; + case kUpb_IsDoneStatus_NotDone: + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + return false; + case kUpb_IsDoneStatus_NeedFallback: + *ptr = + UPB_PRIVATE(upb_EpsCopyInputStream_IsDoneFallback)(e, *ptr, overrun); + if (*ptr) { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e); + } else { + UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e); + } + return *ptr == NULL; + } + UPB_UNREACHABLE(); +} + +UPB_INLINE bool upb_EpsCopyInputStream_CheckSize( + const struct upb_EpsCopyInputStream* e, const char* ptr, int size) { + UPB_ASSERT(size >= 0); + return size <= e->limit - (ptr - e->end); +} + +// Returns a pointer into an input buffer that corresponds to the parsing +// pointer `ptr`. The returned pointer may be the same as `ptr`, but also may +// be different if we are currently parsing out of the patch buffer. +UPB_INLINE const char* UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)( + struct upb_EpsCopyInputStream* e, const char* ptr) { + // This somewhat silly looking add-and-subtract behavior provides provenance + // from the original input buffer's pointer. After optimization it produces + // the same assembly as just casting `(uintptr_t)ptr+input_delta` + // https://godbolt.org/z/zosG88oPn + size_t position = + (uintptr_t)ptr + e->input_delta - (uintptr_t)e->buffer_start; + return e->buffer_start + position; +} + +UPB_INLINE void upb_EpsCopyInputStream_StartCapture( + struct upb_EpsCopyInputStream* e, const char* ptr) { + UPB_ASSERT(e->capture_start == NULL); + e->capture_start = UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)(e, ptr); +} + +UPB_INLINE bool upb_EpsCopyInputStream_EndCapture( + struct upb_EpsCopyInputStream* e, const char* ptr, upb_StringView* sv) { + UPB_ASSERT(e->capture_start != NULL); + if (ptr - e->end > e->limit) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + const char* end = UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)(e, ptr); + sv->data = e->capture_start; + sv->size = end - sv->data; + e->capture_start = NULL; + return true; +} + +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringAlwaysAlias( + struct upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv) { + UPB_ASSERT(size <= PTRDIFF_MAX); + // The `size` must be within the input buffer. If `ptr` is in the input + // buffer, then using the slop bytes is fine (because they are real bytes from + // the tail of the input buffer). If `ptr` is in the patch buffer, then slop + // bytes represent bytes that do not actually exist in the original input + // buffer, so we must fail if the size extends into the slop bytes. + const char* limit = + e->end + (e->input_delta == 0) * kUpb_EpsCopyInputStream_SlopBytes; + if ((ptrdiff_t)size > limit - ptr) { + // For the moment, we consider this an error. In a multi-buffer world, + // it could be that the requested string extends into the next buffer, which + // is not an error and should be recoverable. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + const char* input = UPB_PRIVATE(upb_EpsCopyInputStream_GetInputPtr)(e, ptr); + *sv = upb_StringView_FromDataAndSize(input, size); + return ptr + size; +} + +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringEphemeral( + struct upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv) { + UPB_ASSERT(size <= PTRDIFF_MAX); + // Size must be within the current buffer (including slop bytes). + const char* limit = e->end + kUpb_EpsCopyInputStream_SlopBytes; + if ((ptrdiff_t)size > limit - ptr) { + // For the moment, we consider this an error. In a multi-buffer world, + // it could be that the requested string extends into the next buffer, which + // is not an error and should be recoverable. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + *sv = upb_StringView_FromDataAndSize(ptr, size); + return ptr + size; +} + +UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)( + struct upb_EpsCopyInputStream* e) { + UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit)); +} + +UPB_INLINE ptrdiff_t upb_EpsCopyInputStream_PushLimit( + struct upb_EpsCopyInputStream* e, const char* ptr, size_t size) { + UPB_ASSERT(size <= PTRDIFF_MAX); + ptrdiff_t limit = (ptrdiff_t)size + (ptr - e->end); + ptrdiff_t delta = e->limit - limit; + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); + e->limit = limit; + e->limit_ptr = e->end + UPB_MIN(0, limit); + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); + if (UPB_UNLIKELY(delta < 0)) { + UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(e); + } + return delta; +} + +// Pops the last limit that was pushed on this stream. This may only be called +// once IsDone() returns true. The user must pass the delta that was returned +// from PushLimit(). +UPB_INLINE void upb_EpsCopyInputStream_PopLimit( + struct upb_EpsCopyInputStream* e, const char* ptr, ptrdiff_t saved_delta) { + UPB_ASSERT(ptr - e->end == e->limit); + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); + e->limit += saved_delta; + e->limit_ptr = e->end + UPB_MIN(0, e->limit); + UPB_PRIVATE(upb_EpsCopyInputStream_CheckLimit)(e); +} + +typedef const char* upb_EpsCopyInputStream_ParseDelimitedFunc( + struct upb_EpsCopyInputStream* e, const char* ptr, int size, void* ctx); + +UPB_FORCEINLINE bool upb_EpsCopyInputStream_TryParseDelimitedFast( + struct upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_EpsCopyInputStream_ParseDelimitedFunc* func, void* ctx) { + UPB_ASSERT(size <= PTRDIFF_MAX); + if ((ptrdiff_t)size > e->limit_ptr - *ptr) { + return false; + } + + // Fast case: Sub-message is <128 bytes and fits in the current buffer. + // This means we can preserve limit/limit_ptr verbatim. + const char* saved_limit_ptr = e->limit_ptr; + int saved_limit = e->limit; + e->limit_ptr = *ptr + size; + e->limit = e->limit_ptr - e->end; + UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit)); + *ptr = func(e, *ptr, size, ctx); + e->limit_ptr = saved_limit_ptr; + e->limit = saved_limit; + UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit)); + return true; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct upb_EpsCopyInputStream upb_EpsCopyInputStream; + +// Initializes a upb_EpsCopyInputStream using the contents of the buffer +// [*ptr, size]. Updates `*ptr` as necessary to guarantee that at least +// kUpb_EpsCopyInputStream_SlopBytes are available to read. +UPB_INLINE void upb_EpsCopyInputStream_Init(upb_EpsCopyInputStream* e, + const char** ptr, size_t size); + +// Like the previous function, but registers an error handler that will be +// called for any errors encountered. +UPB_INLINE void upb_EpsCopyInputStream_InitWithErrorHandler( + upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_ErrorHandler* err); + +// Returns true if the stream has an error handler. +// +// This function is marked const, which indicates to the compiler that the +// return value is solely a function of the pointer value. This is not +// entirely true if the stream is reinitialized with +// upb_EpsCopyInputStream_Init*(), so users must not call this function in +// any context where the stream may be reinitialized between calls to this +// function, and the presence of an error handler changes when reinitialized. +UPB_ATTR_CONST +UPB_INLINE bool upb_EpsCopyInputStream_HasErrorHandler( + const upb_EpsCopyInputStream* e); + +// Returns true if the stream is in the error state. A stream enters the error +// state when the user reads past a limit (caught in IsDone()) or the +// ZeroCopyInputStream returns an error. +UPB_INLINE bool upb_EpsCopyInputStream_IsError(upb_EpsCopyInputStream* e); + +// Returns true if the stream has hit a limit, either the current delimited +// limit or the overall end-of-stream. As a side effect, this function may flip +// the pointer to a new buffer if there are less than +// kUpb_EpsCopyInputStream_SlopBytes of data to be read in the current buffer. +// +// Postcondition: if the function returns false, there are at least +// kUpb_EpsCopyInputStream_SlopBytes of data available to read at *ptr. +// +// If this returns true, the user must call upb_EpsCopyInputStream_IsError() +// to distinguish between EOF and error. +UPB_INLINE bool upb_EpsCopyInputStream_IsDone(upb_EpsCopyInputStream* e, + const char** ptr); + +// Returns true if the given delimited field size is valid (it does not extend +// beyond any previously-pushed limits). `ptr` should point to the beginning +// of the field data, after the delimited size. +// +// Note that this does *not* guarantee that all of the data for this field is in +// the current buffer. +UPB_INLINE bool upb_EpsCopyInputStream_CheckSize( + const upb_EpsCopyInputStream* e, const char* ptr, int size); + +// Marks the start of a capture operation. Only one capture operation may be +// active at a time. The capture operation will be finalized by a call to +// upb_EpsCopyInputStream_EndCapture(). The captured string will be returned in +// sv, and will point to the original input buffer if possible. +UPB_INLINE void upb_EpsCopyInputStream_StartCapture(upb_EpsCopyInputStream* e, + const char* ptr); + +// Ends a capture operation and returns the captured string. This may only be +// called once per capture operation. Returns false if the capture operation +// was invalid (the parsing pointer extends beyond the end of the stream). +UPB_INLINE bool upb_EpsCopyInputStream_EndCapture(upb_EpsCopyInputStream* e, + const char* ptr, + upb_StringView* sv); + +// Reads a string from the stream and advances the pointer accordingly. The +// returned string view will always alias the input buffer. +// +// Returns NULL if size extends beyond the end of the current input buffer. +// Currently, we only support a single input buffer, so this function will only +// fail if `size` overflows the end of the stream. +// +// If/when we support multiple input buffers, there may be cases where this +// function returns failure, even if the requested region is valid, because the +// requested region spans multiple buffers. In this case, the caller must +// attempt to read the string using other string reading functions before +// signaling an error. +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringAlwaysAlias( + upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv); + +// Reads a string from the stream and advances the pointer accordingly. The +// returned string view is ephemeral, only valid until the next call to +// upb_EpsCopyInputStream. It may point to the patch buffer. +// +// Returns NULL if size extends beyond the end of the current buffer (which may +// be the patch buffer). +// +// IMPORTANT NOTE: If `size` extends beyond the end of the stream, the returned +// data may contain garbage bytes from the patch buffer. For efficiency, this +// function does not check that `size` is within the current limit or even the +// end of the stream. +// +// The bytes are guaranteed to be safe to read ephemerally, but they may contain +// garbage data that does not correspond to anything in the input. This error +// will be detected later, when calling upb_EpsCopyInputStream_IsDone() (because +// we will not end at the proper limit), but it may result in nonsense bytes +// ending up in the output. +UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringEphemeral( + upb_EpsCopyInputStream* e, const char* ptr, size_t size, + upb_StringView* sv); + +// Pushes a limit onto the stack of limits for the current stream. The limit +// will extend for `size` bytes beyond the position in `ptr`. Future calls to +// upb_EpsCopyInputStream_IsDone() will return `true` when the stream position +// reaches this limit. +// +// Returns a delta that the caller must store and supply to PopLimit() below. +// +// A return value of <0 indicates that `size` is too large, and exceeds a +// previous limit. If this occurs, the stream is in an error state and must no +// longer be used. +UPB_INLINE ptrdiff_t upb_EpsCopyInputStream_PushLimit(upb_EpsCopyInputStream* e, + const char* ptr, + size_t size); + +// Pops the last limit that was pushed on this stream. This may only be called +// once IsDone() returns true. The user must pass the delta that was returned +// from PushLimit(). +UPB_INLINE void upb_EpsCopyInputStream_PopLimit(upb_EpsCopyInputStream* e, + const char* ptr, + ptrdiff_t saved_delta); + +// Tries to perform a fast-path handling of the given delimited message data. +// If the sub-message beginning at `*ptr` and extending for `len` is short and +// fits within this buffer, calls `func` with `ctx` as a parameter, where the +// pushing and popping of limits is handled automatically and with lower cost +// than the normal PushLimit()/PopLimit() sequence. +UPB_FORCEINLINE bool upb_EpsCopyInputStream_TryParseDelimitedFast( + upb_EpsCopyInputStream* e, const char** ptr, size_t size, + upb_EpsCopyInputStream_ParseDelimitedFunc* func, void* ctx); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +// Temporary overloads for functions whose signature has recently changed. +UPB_DEPRECATE_AND_INLINE() +UPB_INLINE void upb_EpsCopyInputStream_Init(upb_EpsCopyInputStream* e, + const char** ptr, size_t size, + bool enable_aliasing) { + upb_EpsCopyInputStream_Init(e, ptr, size); +} +#endif + + +#endif // UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ + +#ifndef UPB_WIRE_READER_H_ +#define UPB_WIRE_READER_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +#ifndef UPB_WIRE_INTERNAL_READER_H_ +#define UPB_WIRE_INTERNAL_READER_H_ + +#include <stddef.h> +#include <stdint.h> + + +// Must be last. + +#define kUpb_WireReader_WireTypeBits 3 +#define kUpb_WireReader_WireTypeMask 7 + +typedef struct { + const char* ptr; + uint64_t val; +} UPB_PRIVATE(_upb_WireReader_LongVarint); + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_PRIVATE(_upb_WireReader_LongVarint) +UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream); +UPB_PRIVATE(_upb_WireReader_LongVarint) +UPB_PRIVATE(_upb_WireReader_ReadLongTag)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream); +UPB_PRIVATE(_upb_WireReader_LongVarint) +UPB_PRIVATE(_upb_WireReader_ReadLongSize)(const char* ptr, uint64_t val, + upb_EpsCopyInputStream* stream); + +UPB_FORCEINLINE const char* upb_WireReader_ReadVarint( + const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 10); + uint8_t byte = *ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } + UPB_PRIVATE(_upb_WireReader_LongVarint) res; + res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(ptr, byte, stream); + *val = res.val; + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr); +} + +UPB_FORCEINLINE const char* upb_WireReader_ReadTag( + const char* ptr, uint32_t* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 5); + uint8_t byte = *ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } + UPB_PRIVATE(_upb_WireReader_LongVarint) res; + res = UPB_PRIVATE(_upb_WireReader_ReadLongTag)(ptr, byte, stream); + *val = res.val; + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr); +} + +UPB_FORCEINLINE const char* upb_WireReader_ReadSize( + const char* ptr, int* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 5); + uint8_t byte = *ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = byte; + return ptr + 1; + } + UPB_PRIVATE(_upb_WireReader_LongVarint) res; + res = UPB_PRIVATE(_upb_WireReader_ReadLongSize)(ptr, byte, stream); + *val = res.val; + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr); +} + +UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { + return tag >> kUpb_WireReader_WireTypeBits; +} + +UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { + return tag & kUpb_WireReader_WireTypeMask; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_INTERNAL_READER_H_ + +#ifndef UPB_WIRE_TYPES_H_ +#define UPB_WIRE_TYPES_H_ + +// A list of types as they are encoded on the wire. +typedef enum { + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; + +#endif /* UPB_WIRE_TYPES_H_ */ + +// Must be last. + +// The upb_WireReader interface is suitable for general-purpose parsing of +// protobuf binary wire format. It is designed to be used along with +// upb_EpsCopyInputStream for buffering, and all parsing routines in this file +// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is +// available to read without any bounds checks. + +#ifdef __cplusplus +extern "C" { +#endif + +// Parses a tag into `tag`, and returns a pointer past the end of the tag, or +// NULL if there was an error in the tag data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_FORCEINLINE const char* upb_WireReader_ReadTag( + const char* ptr, uint32_t* tag, upb_EpsCopyInputStream* stream); + +// Given a tag, returns the field number. +UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag); + +// Given a tag, returns the wire type. +UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag); + +UPB_FORCEINLINE const char* upb_WireReader_ReadVarint( + const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream); + +// Skips data for a varint, returning a pointer past the end of the varint, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_SkipVarint( + const char* ptr, upb_EpsCopyInputStream* stream) { + uint64_t val; + return upb_WireReader_ReadVarint(ptr, &val, stream); +} + +// Reads a varint indicating the size of a delimited field into `size`, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size, + upb_EpsCopyInputStream* stream); + +// Reads a fixed32 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed32( + const char* ptr, void* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 4); + uint32_t uval; + memcpy(&uval, ptr, 4); + uval = upb_BigEndian32(uval); + memcpy(val, &uval, 4); + return ptr + 4; +} + +// Reads a fixed64 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed64( + const char* ptr, void* val, upb_EpsCopyInputStream* stream) { + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 8); + uint64_t uval; + memcpy(&uval, ptr, 8); + uval = upb_BigEndian64(uval); + memcpy(val, &uval, 8); + return ptr + 8; +} + +const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream); + +// Skips data for a group, returning a pointer past the end of the group, or +// NULL if there was an error parsing the group. The `tag` argument should be +// the start group tag that begins the group. The `depth_limit` argument +// indicates how many levels of recursion the group is allowed to have before +// reporting a parse error (this limit exists to protect against stack +// overflow). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipGroup( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + const char* ret = + UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, 100, stream); + return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, ret); +} + +UPB_INLINE const char* _upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + switch (upb_WireReader_GetWireType(tag)) { + case kUpb_WireType_Varint: + return upb_WireReader_SkipVarint(ptr, stream); + case kUpb_WireType_32Bit: + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 4); + return ptr + 4; + case kUpb_WireType_64Bit: + UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 8); + return ptr + 8; + case kUpb_WireType_Delimited: { + int size; + ptr = upb_WireReader_ReadSize(ptr, &size, stream); + if (!ptr || !upb_EpsCopyInputStream_CheckSize(stream, ptr, size)) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } + ptr += size; + return ptr; + } + case kUpb_WireType_StartGroup: + return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, depth_limit, + stream); + case kUpb_WireType_EndGroup: + // Should be handled before now. + default: + // Unknown wire type. + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } +} + +// Skips data for a wire value of any type, returning a pointer past the end of +// the data, or NULL if there was an error parsing the group. The `tag` argument +// should be the tag that was just parsed. The `depth_limit` argument indicates +// how many levels of recursion a group is allowed to have before reporting a +// parse error (this limit exists to protect against stack overflow). +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipValue(ptr, tag, 100, stream); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_READER_H_ + +#ifndef UPB_MESSAGE_COPY_H_ +#define UPB_MESSAGE_COPY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Deep clones a message using the provided target arena. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); + +// Shallow clones a message using the provided target arena. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); + +// Deep clones array contents. +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena); + +// Deep clones map contents. +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena); + +// Deep copies the message from src to dst. +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m, upb_Arena* arena); + +// Shallow copies the message from src to dst. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MESSAGE_COPY_H_ +#ifndef GOOGLE_UPB_UPB_MESSAGE_MERGE_H__ +#define GOOGLE_UPB_UPB_MESSAGE_MERGE_H__ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mt, + const upb_ExtensionRegistry* extreg, + upb_Arena* arena); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // GOOGLE_UPB_UPB_MESSAGE_MERGE_H__ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ + +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE char _upb_ToBase92(int8_t ch) { + extern const char _kUpb_ToBase92[]; + UPB_ASSERT(0 <= ch && ch < 92); + return _kUpb_ToBase92[ch]; +} + +UPB_INLINE char _upb_FromBase92(uint8_t ch) { + extern const int8_t _kUpb_FromBase92[]; + if (' ' > ch || ch > '~') return -1; + return _kUpb_FromBase92[ch - ' ']; +} + +UPB_INLINE const char* _upb_Base92_DecodeVarint(const char* ptr, + const char* end, char first_ch, + uint8_t min, uint8_t max, + uint32_t* out_val) { + uint32_t val = 0; + uint32_t shift = 0; + const int bits_per_char = + upb_Log2Ceiling(_upb_FromBase92(max) - _upb_FromBase92(min)); + char ch = first_ch; + while (1) { + uint32_t bits = _upb_FromBase92(ch) - _upb_FromBase92(min); + val |= bits << shift; + if (ptr == end || *ptr < min || max < *ptr) { + *out_val = val; + UPB_ASSUME(ptr != NULL); + return ptr; + } + ch = *ptr++; + shift += bits_per_char; + if (shift >= 32) return NULL; + } +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ + + +// Must be last. + +// upb_MdDecoder: used internally for decoding MiniDescriptors for messages, +// extensions, and enums. +typedef struct { + const char* end; + upb_Status* status; + jmp_buf err; +} upb_MdDecoder; + +UPB_PRINTF(2, 3) +UPB_NORETURN UPB_INLINE void upb_MdDecoder_ErrorJmp(upb_MdDecoder* d, + const char* fmt, ...) { + if (d->status) { + va_list argp; + upb_Status_SetErrorMessage(d->status, "Error building mini table: "); + va_start(argp, fmt); + upb_Status_VAppendErrorFormat(d->status, fmt, argp); + va_end(argp); + } + UPB_LONGJMP(d->err, 1); +} + +UPB_INLINE void upb_MdDecoder_CheckOutOfMemory(upb_MdDecoder* d, + const void* ptr) { + if (!ptr) upb_MdDecoder_ErrorJmp(d, "Out of memory"); +} + +UPB_INLINE const char* upb_MdDecoder_DecodeBase92Varint( + upb_MdDecoder* d, const char* ptr, char first_ch, uint8_t min, uint8_t max, + uint32_t* out_val) { + ptr = _upb_Base92_DecodeVarint(ptr, d->end, first_ch, min, max, out_val); + if (!ptr) upb_MdDecoder_ErrorJmp(d, "Overlong varint"); + return ptr; +} + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_WIRE_CONSTANTS_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_WIRE_CONSTANTS_H_ + + +// Must be last. + +typedef enum { + kUpb_EncodedType_Double = 0, + kUpb_EncodedType_Float = 1, + kUpb_EncodedType_Fixed32 = 2, + kUpb_EncodedType_Fixed64 = 3, + kUpb_EncodedType_SFixed32 = 4, + kUpb_EncodedType_SFixed64 = 5, + kUpb_EncodedType_Int32 = 6, + kUpb_EncodedType_UInt32 = 7, + kUpb_EncodedType_SInt32 = 8, + kUpb_EncodedType_Int64 = 9, + kUpb_EncodedType_UInt64 = 10, + kUpb_EncodedType_SInt64 = 11, + kUpb_EncodedType_OpenEnum = 12, + kUpb_EncodedType_Bool = 13, + kUpb_EncodedType_Bytes = 14, + kUpb_EncodedType_String = 15, + kUpb_EncodedType_Group = 16, + kUpb_EncodedType_Message = 17, + kUpb_EncodedType_ClosedEnum = 18, + + kUpb_EncodedType_RepeatedBase = 20, +} upb_EncodedType; + +typedef enum { + kUpb_EncodedFieldModifier_FlipPacked = 1 << 0, + kUpb_EncodedFieldModifier_IsRequired = 1 << 1, + kUpb_EncodedFieldModifier_IsProto3Singular = 1 << 2, + kUpb_EncodedFieldModifier_FlipValidateUtf8 = 1 << 3, +} upb_EncodedFieldModifier; + +enum { + kUpb_EncodedValue_MinField = ' ', + kUpb_EncodedValue_MaxField = 'I', + kUpb_EncodedValue_MinModifier = 'L', + kUpb_EncodedValue_MaxModifier = '[', + kUpb_EncodedValue_End = '^', + kUpb_EncodedValue_MinSkip = '_', + kUpb_EncodedValue_MaxSkip = '~', + kUpb_EncodedValue_OneofSeparator = '~', + kUpb_EncodedValue_FieldSeparator = '|', + kUpb_EncodedValue_MinOneofField = ' ', + kUpb_EncodedValue_MaxOneofField = 'b', + kUpb_EncodedValue_MaxEnumMask = 'A', +}; + +enum { + kUpb_EncodedVersion_EnumV1 = '!', + kUpb_EncodedVersion_ExtensionV1 = '#', + kUpb_EncodedVersion_MapV1 = '%', + kUpb_EncodedVersion_MessageV1 = '$', + kUpb_EncodedVersion_MessageSetV1 = '&', +}; + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_WIRE_CONSTANTS_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_ + +// Must be last. + +typedef enum { + kUpb_FieldModifier_IsRepeated = 1 << 0, + kUpb_FieldModifier_IsPacked = 1 << 1, + kUpb_FieldModifier_IsClosedEnum = 1 << 2, + kUpb_FieldModifier_IsProto3Singular = 1 << 3, + kUpb_FieldModifier_IsRequired = 1 << 4, + kUpb_FieldModifier_ValidateUtf8 = 1 << 5, +} kUpb_FieldModifier; + +// These modifiers are also used on the wire. +typedef enum { + kUpb_MessageModifier_ValidateUtf8 = 1 << 0, + kUpb_MessageModifier_DefaultIsPacked = 1 << 1, + kUpb_MessageModifier_IsExtendable = 1 << 2, +} kUpb_MessageModifier; + + +#endif // UPB_MINI_DESCRIPTOR_INTERNAL_MODIFIERS_H_ + +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ + +#include <stdint.h> + + +// Must be last. + +// If the input buffer has at least this many bytes available, the encoder call +// is guaranteed to succeed (as long as field number order is maintained). +#define kUpb_MtDataEncoder_MinSize 16 + +typedef struct { + char* end; // Limit of the buffer passed as a parameter. + // Aliased to internal-only members in .cc. + char internal[32]; +} upb_MtDataEncoder; + +#ifdef __cplusplus +extern "C" { +#endif + +// Encodes field/oneof information for a given message. The sequence of calls +// should look like: +// +// upb_MtDataEncoder e; +// char buf[256]; +// char* ptr = buf; +// e.end = ptr + sizeof(buf); +// unit64_t msg_mod = ...; // bitwise & of kUpb_MessageModifiers or zero +// ptr = upb_MtDataEncoder_StartMessage(&e, ptr, msg_mod); +// // Fields *must* be in field number order. +// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...); +// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...); +// ptr = upb_MtDataEncoder_PutField(&e, ptr, ...); +// +// // If oneofs are present. Oneofs must be encoded after regular fields. +// ptr = upb_MiniTable_StartOneof(&e, ptr) +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// +// ptr = upb_MiniTable_StartOneof(&e, ptr); +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// ptr = upb_MiniTable_PutOneofField(&e, ptr, ...); +// +// Oneofs must be encoded after all regular fields. +char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr, + uint64_t msg_mod); +char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod); +char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr); +char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr, + uint32_t field_num); + +// Encodes the set of values for a given enum. The values must be given in +// order (after casting to uint32_t), and repeats are not allowed. +char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr); +char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr, + uint32_t val); +char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr); + +// Encodes an entire mini descriptor for an extension. +char* upb_MtDataEncoder_EncodeExtension(upb_MtDataEncoder* e, char* ptr, + upb_FieldType type, uint32_t field_num, + uint64_t field_mod); + +// Encodes an entire mini descriptor for a map. +char* upb_MtDataEncoder_EncodeMap(upb_MtDataEncoder* e, char* ptr, + upb_FieldType key_type, + upb_FieldType value_type, uint64_t key_mod, + uint64_t value_mod); + +// Encodes an entire mini descriptor for a message set. +char* upb_MtDataEncoder_EncodeMessageSet(upb_MtDataEncoder* e, char* ptr); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_DESCRIPTOR_INTERNAL_ENCODE_H_ */ + +#ifndef UPB_MINI_TABLE_GENERATED_REGISTRY_H_ +#define UPB_MINI_TABLE_GENERATED_REGISTRY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Generated registry: a global singleton that gathers all extensions linked + * into the binary. + * + * This singleton is thread-safe and lock-free, implemented using atomics. The + * registry is lazily initialized the first time it is loaded. When all + * references are released, the registry will be destroyed. New loads + * afterwards will simply reload the same registry as needed. + * + * The extension minitables are registered in gencode using linker arrays. Each + * .proto file produces a weak, hidden, constructor function that adds all + * visible extensions from the array into the registry. In each binary, only + * one copy of the constructor will actually be preserved by the linker, and + * that copy will add all of the extensions for the entire binary. All of these + * are added to a global linked list of minitables pre-main, which are then used + * to construct this singleton as needed. + */ + +typedef struct upb_GeneratedRegistryRef upb_GeneratedRegistryRef; + +// Loads the generated registry, returning a reference to it. The reference +// must be held for the lifetime of any ExtensionRegistry obtained from it. +// +// Returns NULL on failure. +UPB_API const upb_GeneratedRegistryRef* upb_GeneratedRegistry_Load(void); + +// Releases a reference to the generated registry. This may destroy the +// registry if there are no other references to it. +// +// NULL is a valid argument and is simply ignored for easier error handling in +// callers. +UPB_API void upb_GeneratedRegistry_Release(const upb_GeneratedRegistryRef* r); + +// Returns the extension registry contained by a reference to the generated +// registry. +// +// The reference must be held for the lifetime of the registry. +UPB_API const upb_ExtensionRegistry* upb_GeneratedRegistry_Get( + const upb_GeneratedRegistryRef* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_MINI_TABLE_GENERATED_REGISTRY_H_ + +#ifndef UPB_REFLECTION_DEF_POOL_INTERNAL_H_ +#define UPB_REFLECTION_DEF_POOL_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s); +size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s); +upb_ExtensionRegistry* _upb_DefPool_ExtReg(const upb_DefPool* s); + +bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext, + const upb_FieldDef* f); +bool _upb_DefPool_InsertSym(upb_DefPool* s, upb_StringView sym, upb_value v, + upb_Status* status); +bool _upb_DefPool_LookupSym(const upb_DefPool* s, const char* sym, size_t size, + upb_value* v); + +void** _upb_DefPool_ScratchData(const upb_DefPool* s); +size_t* _upb_DefPool_ScratchSize(const upb_DefPool* s); +void _upb_DefPool_SetPlatform(upb_DefPool* s, upb_MiniTablePlatform platform); + +// For generated code only: loads a generated descriptor. +typedef struct _upb_DefPool_Init { + struct _upb_DefPool_Init** deps; // Dependencies of this file. + const upb_MiniTableFile* layout; + const char* filename; + upb_StringView descriptor; // Serialized descriptor. +} _upb_DefPool_Init; + +bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init); + +// Should only be directly called by tests. This variant lets us suppress +// the use of compiled-in tables, forcing a rebuild of the tables at runtime. +bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, + bool rebuild_minitable); + +const upb_ExtensionRegistry* _upb_DefPool_GeneratedExtensionRegistry( + const upb_DefPool* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_POOL_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_DEF_BUILDER_INTERNAL_H_ +#define UPB_REFLECTION_DEF_BUILDER_INTERNAL_H_ + +#include <setjmp.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + + +// Must be last. + +// We want to copy the options verbatim into the destination options proto. +// We use serialize+parse as our deep copy. +#define UPB_DEF_SET_OPTIONS(target, desc_type, options_type, proto) \ + if (google_protobuf_##desc_type##_has_options(proto)) { \ + size_t size; \ + char* pb = google_protobuf_##options_type##_serialize( \ + google_protobuf_##desc_type##_options(proto), ctx->tmp_arena, &size); \ + if (!pb) _upb_DefBuilder_OomErr(ctx); \ + target = google_protobuf_##options_type##_parse_ex( \ + pb, size, _upb_DefPool_GeneratedExtensionRegistry(ctx->symtab), 0, \ + _upb_DefBuilder_Arena(ctx)); \ + if (!target) _upb_DefBuilder_OomErr(ctx); \ + } else { \ + target = (const google_protobuf_##options_type*)kUpbDefOptDefault; \ + } + +#ifdef __cplusplus +extern "C" { +#endif + +struct upb_DefBuilder { + upb_DefPool* symtab; + upb_strtable feature_cache; // Caches features by identity. + google_protobuf_FeatureSet* legacy_features; // For computing legacy features. + char* tmp_buf; // Temporary buffer in tmp_arena. + size_t tmp_buf_size; // Size of temporary buffer. + upb_FileDef* file; // File we are building. + upb_Arena* arena; // Allocate defs here. + upb_Arena* tmp_arena; // For temporary allocations. + upb_Status* status; // Record errors here. + const upb_MiniTableFile* layout; // NULL if we should build layouts. + upb_MiniTablePlatform platform; // Platform we are targeting. + int enum_count; // Count of enums built so far. + int msg_count; // Count of messages built so far. + int ext_count; // Count of extensions built so far. + jmp_buf err; // longjmp() on error. +}; + +extern const char* kUpbDefOptDefault; + +// ctx->status has already been set elsewhere so just fail/longjmp() +UPB_NORETURN void _upb_DefBuilder_FailJmp(upb_DefBuilder* ctx); + +UPB_NORETURN void _upb_DefBuilder_Errf(upb_DefBuilder* ctx, const char* fmt, + ...) UPB_PRINTF(2, 3); +UPB_NORETURN void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx); + +const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx, + const char* prefix, + upb_StringView name); + +// Given a symbol and the base symbol inside which it is defined, +// find the symbol's definition. +const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, + const char* from_name_dbg, + const char* base, upb_StringView sym, + upb_deftype_t* type); + +const void* _upb_DefBuilder_Resolve(upb_DefBuilder* ctx, + const char* from_name_dbg, const char* base, + upb_StringView sym, upb_deftype_t type); + +char _upb_DefBuilder_ParseEscape(upb_DefBuilder* ctx, const upb_FieldDef* f, + const char** src, const char* end); + +const char* _upb_DefBuilder_FullToShort(const char* fullname); + +UPB_INLINE void* _upb_DefBuilder_Alloc(upb_DefBuilder* ctx, size_t bytes) { + if (bytes == 0) return NULL; + void* ret = upb_Arena_Malloc(ctx->arena, bytes); + if (!ret) _upb_DefBuilder_OomErr(ctx); + return ret; +} + +/* Allocates an array of `count` elements, checking for size_t overflow */ +UPB_INLINE void* _upb_DefBuilder_AllocCounted(upb_DefBuilder* ctx, size_t size, + size_t count) { + if (count == 0) return NULL; + if (SIZE_MAX / size < count) { + _upb_DefBuilder_OomErr(ctx); + } + return _upb_DefBuilder_Alloc(ctx, size * count); +} + +#define UPB_DEFBUILDER_ALLOCARRAY(ctx, type, count) \ + ((type*)_upb_DefBuilder_AllocCounted(ctx, sizeof(type), (count))) + +// Adds a symbol |v| to the symtab, which must be a def pointer previously +// packed with pack_def(). The def's pointer to upb_FileDef* must be set before +// adding, so we know which entries to remove if building this file fails. +UPB_INLINE void _upb_DefBuilder_Add(upb_DefBuilder* ctx, const char* name, + upb_value v) { + upb_StringView sym = {.data = name, .size = strlen(name)}; + bool ok = _upb_DefPool_InsertSym(ctx->symtab, sym, v, ctx->status); + if (!ok) _upb_DefBuilder_FailJmp(ctx); +} + +UPB_INLINE upb_Arena* _upb_DefBuilder_Arena(const upb_DefBuilder* ctx) { + return ctx->arena; +} + +UPB_INLINE upb_FileDef* _upb_DefBuilder_File(const upb_DefBuilder* ctx) { + return ctx->file; +} + +// This version of CheckIdent() is only called by other, faster versions after +// they detect a parsing error. +void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, + bool full); + +// Verify a full identifier string. This is slightly more complicated than +// verifying a relative identifier string because we must track '.' chars. +UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, + upb_StringView name) { + bool good = name.size > 0; + bool start = true; + + for (size_t i = 0; i < name.size; i++) { + const char c = name.data[i]; + const char d = c | 0x20; // force lowercase + const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); + const bool is_numer = ('0' <= c) & (c <= '9') & !start; + const bool is_dot = (c == '.') & !start; + + good &= is_alpha | is_numer | is_dot; + start = is_dot; + } + + if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); +} + +UPB_INLINE bool _upb_DefBuilder_IsLegacyEdition(google_protobuf_Edition edition) { + // Should only be called for a real edition, not a placeholder like + // EDITION_LEGACY. + UPB_ASSERT(edition >= google_protobuf_EDITION_PROTO2); + return edition <= google_protobuf_EDITION_PROTO3; +} + +// Returns true if the returned feature set is new and must be populated. +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const google_protobuf_FeatureSet* parent, + upb_StringView key, + google_protobuf_FeatureSet** set); + +const google_protobuf_FeatureSet* _upb_DefBuilder_DoResolveFeatures( + upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent, + const google_protobuf_FeatureSet* child, bool is_implicit); + +UPB_INLINE const google_protobuf_FeatureSet* _upb_DefBuilder_ResolveFeatures( + upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent, + const google_protobuf_FeatureSet* child) { + return _upb_DefBuilder_DoResolveFeatures(ctx, parent, child, false); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DEF_BUILDER_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_FILE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_FILE_DEF_INTERNAL_H_ + +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +const upb_MiniTableExtension* _upb_FileDef_ExtensionMiniTable( + const upb_FileDef* f, int i); +const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f); +const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f); +bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f); +bool _upb_FileDef_ImplicitFieldPresenceDisabled(const upb_FileDef* f); + +// upb_FileDef_Package() returns "" if f->package is NULL, this does not. +const char* _upb_FileDef_RawPackage(const upb_FileDef* f); + +void _upb_FileDef_Create(upb_DefBuilder* ctx, + const google_protobuf_FileDescriptorProto* file_proto); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FILE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_MESSAGE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_MESSAGE_DEF_INTERNAL_H_ + +#include <stddef.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i); +bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m); +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_IsValidExtensionNumber(const upb_MessageDef* m, int n); +void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m); +void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, + const upb_MessageDef* m); +void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m); + +// Allocate and initialize an array of |n| message defs. +upb_MessageDef* _upb_MessageDefs_New( + upb_DefBuilder* ctx, int n, const google_protobuf_DescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ +#define UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + +// This file contains the serialized FeatureSetDefaults object for +// language-independent features and (possibly at some point) for upb-specific +// features. This is used for feature resolution under Editions. +// NOLINTBEGIN +// clang-format off +#define UPB_INTERNAL_UPB_EDITION_DEFAULTS "\n\027\030\204\007\"\000*\020\010\001\020\002\030\002 \003(\0010\0028\002@\001\n\027\030\347\007\"\000*\020\010\002\020\001\030\001 \002(\0010\0018\002@\001\n\027\030\350\007\"\014\010\001\020\001\030\001 \002(\0010\001*\0048\002@\001\n\027\030\351\007\"\020\010\001\020\001\030\001 \002(\0010\0018\001@\002*\000\n\027\030\217N\"\020\010\001\020\001\030\001 \002(\0010\0018\003@\002*\000 \346\007(\351\007" +// clang-format on +// NOLINTEND + +#endif // UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + +#ifndef UPB_REFLECTION_DESC_STATE_INTERNAL_H_ +#define UPB_REFLECTION_DESC_STATE_INTERNAL_H_ + + +// Must be last. + +// Manages the storage for mini descriptor strings as they are being encoded. +// TODO: 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 + +UPB_INLINE void _upb_DescState_Init(upb_DescState* d) { + d->bufsize = kUpb_MtDataEncoder_MinSize * 2; + d->buf = NULL; + d->ptr = NULL; +} + +bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_DESC_STATE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ENUM_DEF_INTERNAL_H_ +#define UPB_REFLECTION_ENUM_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +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_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); + +// Allocate and initialize an array of |n| enum defs. +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, + const upb_MessageDef* containing_type); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ENUM_RESERVED_RANGE_INTERNAL_H_ +#define UPB_REFLECTION_ENUM_RESERVED_RANGE_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r, + int i); + +// Allocate and initialize an array of |n| reserved ranges owned by |e|. +upb_EnumReservedRange* _upb_EnumReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos, + const upb_EnumDef* e); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_RESERVED_RANGE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_ENUM_VALUE_DEF_INTERNAL_H_ + +#include <stddef.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i); + +// Allocate and initialize an array of |n| enum value defs owned by |e|. +upb_EnumValueDef* _upb_EnumValueDefs_New( + upb_DefBuilder* ctx, const char* prefix, int n, + const google_protobuf_EnumValueDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_EnumDef* e, bool* is_sorted); + +const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, + size_t n, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_VALUE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_INTERNAL_STRDUP2_H_ +#define UPB_REFLECTION_INTERNAL_STRDUP2_H_ + +#include <stddef.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Variant that works with a length-delimited rather than NULL-delimited string, +// as supported by strtable. +char* upb_strdup2(const char* s, size_t len, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_INTERNAL_STRDUP2_H_ */ + +#ifndef UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ +#define UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i); + +// Allocate and initialize an array of |n| extension ranges owned by |m|. +upb_ExtensionRange* _upb_ExtensionRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ExtensionRange* const* protos, + const google_protobuf_FeatureSet* parent_features, const upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_FIELD_DEF_INTERNAL_H_ +#define UPB_REFLECTION_FIELD_DEF_INTERNAL_H_ + +#include <stdint.h> + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i); + +bool _upb_FieldDef_IsClosedEnum(const upb_FieldDef* f); +bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f); +int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f); +uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f); +void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, + upb_FieldDef* f); +void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, + const upb_FieldDef* f); + +// Allocate and initialize an array of |n| extensions (field defs). +upb_FieldDef* _upb_Extensions_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m); + +// Allocate and initialize an array of |n| field defs. +upb_FieldDef* _upb_FieldDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_FieldDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, const char* prefix, + upb_MessageDef* m, bool* is_sorted); + +// Allocate and return a list of pointers to the |n| field defs in |ff|, +// sorted by field number. +const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n, + upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_FIELD_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_ONEOF_DEF_INTERNAL_H_ +#define UPB_REFLECTION_ONEOF_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i); +void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o, + const upb_FieldDef* f, const char* name, size_t size); + +// Allocate and initialize an array of |n| oneof defs owned by |m|. +upb_OneofDef* _upb_OneofDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_OneofDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_MessageDef* m); + +size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ONEOF_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ +#define UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int i); + +// Allocate and initialize an array of |n| service defs. +upb_ServiceDef* _upb_ServiceDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_ServiceDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features); + +void _upb_ServiceDef_InsertMethod(upb_DefBuilder* ctx, upb_ServiceDef* s, + const upb_MethodDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_MESSAGE_RESERVED_RANGE_INTERNAL_H_ +#define UPB_REFLECTION_MESSAGE_RESERVED_RANGE_INTERNAL_H_ + + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_MESSAGE_RESERVED_RANGE_H_ +#define UPB_REFLECTION_MESSAGE_RESERVED_RANGE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t upb_MessageReservedRange_Start(const upb_MessageReservedRange* r); +int32_t upb_MessageReservedRange_End(const upb_MessageReservedRange* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_RESERVED_RANGE_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_MessageReservedRange* _upb_MessageReservedRange_At( + const upb_MessageReservedRange* r, int i); + +// Allocate and initialize an array of |n| reserved ranges owned by |m|. +upb_MessageReservedRange* _upb_MessageReservedRanges_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_DescriptorProto_ReservedRange* const* protos, + const upb_MessageDef* m); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_MESSAGE_RESERVED_RANGE_INTERNAL_H_ */ + +#ifndef UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ +#define UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i); + +// Allocate and initialize an array of |n| method defs owned by |s|. +upb_MethodDef* _upb_MethodDefs_New( + upb_DefBuilder* ctx, int n, + const google_protobuf_MethodDescriptorProto* const* protos, + const google_protobuf_FeatureSet* parent_features, upb_ServiceDef* s); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_METHOD_DEF_INTERNAL_H_ */ + +#ifndef UPB_UTIL_DEF_TO_PROTO_H_ +#define UPB_UTIL_DEF_TO_PROTO_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +// Functions for converting defs back to the equivalent descriptor proto. +// Ultimately the goal is that a round-trip proto->def->proto is lossless. Each +// function returns a new proto created in arena `a`, or NULL if memory +// allocation failed. +google_protobuf_DescriptorProto* upb_MessageDef_ToProto(const upb_MessageDef* m, + upb_Arena* a); +google_protobuf_EnumDescriptorProto* upb_EnumDef_ToProto(const upb_EnumDef* e, + upb_Arena* a); +google_protobuf_EnumValueDescriptorProto* upb_EnumValueDef_ToProto( + const upb_EnumValueDef* e, upb_Arena* a); +google_protobuf_FieldDescriptorProto* upb_FieldDef_ToProto( + const upb_FieldDef* f, upb_Arena* a); +google_protobuf_OneofDescriptorProto* upb_OneofDef_ToProto( + const upb_OneofDef* o, upb_Arena* a); +google_protobuf_FileDescriptorProto* upb_FileDef_ToProto(const upb_FileDef* f, + upb_Arena* a); +google_protobuf_MethodDescriptorProto* upb_MethodDef_ToProto( + const upb_MethodDef* m, upb_Arena* a); +google_protobuf_ServiceDescriptorProto* upb_ServiceDef_ToProto( + const upb_ServiceDef* s, upb_Arena* a); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* UPB_UTIL_DEF_TO_PROTO_H_ */ + +// IWYU pragma: private, include "upb/reflection/def.h" + +#ifndef UPB_REFLECTION_ENUM_RESERVED_RANGE_H_ +#define UPB_REFLECTION_ENUM_RESERVED_RANGE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t upb_EnumReservedRange_Start(const upb_EnumReservedRange* r); +int32_t upb_EnumReservedRange_End(const upb_EnumReservedRange* r); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_REFLECTION_ENUM_RESERVED_RANGE_H_ */ + +#ifndef UPB_WIRE_INTERNAL_CONSTANTS_H_ +#define UPB_WIRE_INTERNAL_CONSTANTS_H_ + +#define kUpb_WireFormat_DefaultDepthLimit 100 + +// MessageSet wire format is: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required bytes message = 3; +// } +// } + +enum { + kUpb_MsgSet_Item = 1, + kUpb_MsgSet_TypeId = 2, + kUpb_MsgSet_Message = 3, +}; + +#endif /* UPB_WIRE_INTERNAL_CONSTANTS_H_ */ + +/* + * Internal implementation details of the decoder that are shared between + * decode.c and decode_fast.c. + */ + +#ifndef UPB_WIRE_INTERNAL_DECODER_H_ +#define UPB_WIRE_INTERNAL_DECODER_H_ + +#include <setjmp.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include "utf8_range.h" + +// Must be last. + +#define DECODE_NOGROUP (uint32_t)-1 + +typedef struct upb_Decoder { + upb_EpsCopyInputStream input; + const upb_ExtensionRegistry* extreg; + upb_Message* original_msg; // Pointer to preserve data to + int depth; // Tracks recursion depth to bound stack usage. + uint32_t end_group; // field number of END_GROUP tag, else DECODE_NOGROUP. + uint16_t options; + bool missing_required; + bool message_is_done; + union { + upb_Arena arena; + void* foo[UPB_ARENA_SIZE_HACK / sizeof(void*)]; + }; + upb_ErrorHandler err; + +#ifndef NDEBUG + char* trace_buf; + char* trace_ptr; + char* trace_end; +#endif +} upb_Decoder; + +UPB_INLINE const char* upb_Decoder_Init(upb_Decoder* d, const char* buf, + size_t size, + const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena, + char* trace_buf, size_t trace_size) { + upb_ErrorHandler_Init(&d->err); + upb_EpsCopyInputStream_InitWithErrorHandler(&d->input, &buf, size, &d->err); + + UPB_STATIC_ASSERT((int)kUpb_DecodeStatus_Ok == (int)kUpb_ErrorCode_Ok, + "mismatched error codes"); + UPB_STATIC_ASSERT( + (int)kUpb_DecodeStatus_OutOfMemory == (int)kUpb_ErrorCode_OutOfMemory, + "mismatched error codes"); + UPB_STATIC_ASSERT( + (int)kUpb_DecodeStatus_Malformed == (int)kUpb_ErrorCode_Malformed, + "mismatched error codes"); + + if (options & kUpb_DecodeOption_AlwaysValidateUtf8) { + // Fasttable decoder does not support this option. + options |= kUpb_DecodeOption_DisableFastTable; + } + + d->extreg = extreg; + d->depth = upb_DecodeOptions_GetEffectiveMaxDepth(options); + d->end_group = DECODE_NOGROUP; + d->options = (uint16_t)options; + d->missing_required = false; + d->message_is_done = false; +#ifndef NDEBUG + d->trace_buf = trace_buf; + d->trace_ptr = trace_buf; + d->trace_end = UPB_PTRADD(trace_buf, trace_size); +#endif + if (trace_buf) *trace_buf = 0; // Null-terminate. + + // Violating the encapsulation of the arena for performance reasons. + // This is a temporary arena that we swap into and swap out of when we are + // done. The temporary arena only needs to be able to handle allocation, + // not fuse or free, so it does not need many of the members to be initialized + // (particularly parent_or_count). + UPB_PRIVATE(_upb_Arena_SwapIn)(&d->arena, arena); + return buf; +} + +UPB_INLINE upb_DecodeStatus upb_Decoder_Destroy(upb_Decoder* d, + upb_Arena* arena) { + UPB_PRIVATE(_upb_Arena_SwapOut)(arena, &d->arena); + return (upb_DecodeStatus)d->err.code; +} + +#ifndef NDEBUG +UPB_INLINE bool _upb_Decoder_TraceBufferFull(upb_Decoder* d) { + return d->trace_ptr == d->trace_end - 1; +} + +UPB_INLINE bool _upb_Decoder_TraceBufferAlmostFull(upb_Decoder* d) { + return d->trace_ptr == d->trace_end - 2; +} +#endif + +UPB_INLINE char* _upb_Decoder_TraceNext(upb_Decoder* d) { +#ifndef NDEBUG + return _upb_Decoder_TraceBufferAlmostFull(d) ? NULL : d->trace_ptr + 1; +#else + return NULL; +#endif +} + +UPB_INLINE char* _upb_Decoder_TracePtr(upb_Decoder* d) { +#ifndef NDEBUG + return d->trace_ptr; +#else + return NULL; +#endif +} + +// Trace events are used to trace the progress of the decoder. +// Events: +// 'D' Fast dispatch +// 'F' Field successfully parsed fast. +// '<' Fallback to MiniTable parser. +// 'M' Field successfully parsed with MiniTable. +// 'X' Truncated -- trace buffer is full, further events were discarded. +UPB_INLINE void _upb_Decoder_Trace(upb_Decoder* d, char event) { +#ifndef NDEBUG + if (d->trace_ptr == NULL) return; + if (_upb_Decoder_TraceBufferFull(d)) { + d->trace_ptr[-1] = 'X'; // Truncated. + return; + } + d->trace_ptr[0] = event; + d->trace_ptr[1] = '\0'; + d->trace_ptr++; +#endif +}; + +UPB_INLINE +bool _upb_Decoder_VerifyUtf8Inline(const char* ptr, int len) { + return utf8_range_IsValid(ptr, len); +} + +const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, + const upb_Message* msg, + const upb_MiniTable* m); + +/* x86-64 pointers always have the high 16 bits matching. So we can shift + * left 8 and right 8 without loss of information. */ +UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { + return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask); +} + +UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { + return (const upb_MiniTable*)(table >> 8); +} + +const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, + upb_Message* msg, + const upb_MiniTable* layout); + +UPB_INLINE bool _upb_Decoder_FieldRequiresUtf8Validation( + const upb_Decoder* d, const upb_MiniTableField* field) { + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_String) return true; + + if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes && + (field->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) && + (d->options & kUpb_DecodeOption_AlwaysValidateUtf8)) { + return true; + } + + return false; +} + +UPB_INLINE bool _upb_Decoder_ReadString(upb_Decoder* d, const char** ptr, + size_t size, upb_StringView* sv, + bool validate_utf8) { + upb_StringView tmp; + *ptr = + upb_EpsCopyInputStream_ReadStringAlwaysAlias(&d->input, *ptr, size, &tmp); + if (*ptr == NULL) return false; + if (validate_utf8 && !utf8_range_IsValid(tmp.data, tmp.size)) { + upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_BadUtf8); + return false; + } + if ((d->options & kUpb_DecodeOption_AliasString) == 0) { + char* data = (char*)upb_Arena_Malloc(&d->arena, tmp.size); + if (!data) return false; + memcpy(data, tmp.data, tmp.size); + tmp.data = data; + } + *sv = tmp; + return true; +} + + +#endif /* UPB_WIRE_INTERNAL_DECODER_H_ */ +#ifndef GOOGLE_UPB_UPB_WIRE_WRITER_H__ +#define GOOGLE_UPB_UPB_WIRE_WRITER_H__ + +#include <stdint.h> + +// Must be last. + +UPB_FORCEINLINE uint32_t +UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) { + // Calculate how many bytes of the possible 10 bytes we will *not* encode, + // because they are part of a zero prefix. For the number 300, it would use 2 + // bytes encoded, so the number of bytes to skip would be 8. Adding 7 to the + // clz input ensures that we're rounding up. + return (((uint32_t)clz + 7) * 9) >> 6; +} + + +#endif // GOOGLE_UPB_UPB_WIRE_WRITER_H__ + +// This should #undef all macros #defined in def.inc + +#undef UPB_SIZE +#undef UPB_PTR_AT +#undef UPB_SIZEOF_FLEX +#undef UPB_SIZEOF_FLEX_WOULD_OVERFLOW +#undef UPB_MAPTYPE_STRING +#undef UPB_EXPORT +#undef UPB_INLINE +#undef UPB_API +#undef UPBC_API +#undef UPB_API_INLINE +#undef UPB_API_INLINE_IF_NOT_GCC +#undef UPB_ALIGN_UP +#undef UPB_ALIGN_DOWN +#undef UPB_ALIGN_MALLOC +#undef UPB_ALIGN_OF +#undef UPB_ALIGN_AS +#undef UPB_STATIC_ASSERT +#undef UPB_STATIC_ASSERT_CONCAT +#undef UPB_STATIC_ASSERT_CONCAT_IMPL +#undef UPB_LIKELY +#undef UPB_UNLIKELY +#undef UPB_UNPREDICTABLE +#undef UPB_FORCEINLINE +#undef UPB_NOINLINE +#undef UPB_NORETURN +#undef UPB_PRINTF +#undef UPB_NODEREF +#undef UPB_MAX +#undef UPB_MIN +#undef UPB_UNUSED +#undef UPB_ASSUME +#undef UPB_ASSERT +#undef UPB_UNREACHABLE +#undef UPB_DEFAULT_MAX_BLOCK_SIZE +#undef UPB_SETJMP +#undef UPB_LONGJMP +#undef UPB_PTRADD +#undef UPB_MUSTTAIL +#undef UPB_PRESERVE_MOST +#undef UPB_PRESERVE_NONE +#undef UPB_FASTTABLE_SUPPORTED +#undef UPB_FASTTABLE_MASK +#undef UPB_FASTTABLE +#undef UPB_FASTTABLE_INIT +#undef UPB_POISON_MEMORY_REGION +#undef UPB_UNPOISON_MEMORY_REGION +#undef UPB_ASAN +#undef UPB_HWASAN +#undef UPB_HWASAN_POISON_TAG +#undef UPB_MSAN +#undef UPB_MALLOC_ALIGN +#undef UPB_TSAN +#undef UPB_DEPRECATED +#undef UPB_GNUC_MIN +#undef UPB_DESCRIPTOR_UPB_H_FILENAME +#undef UPB_DESC_MINITABLE +#undef UPB_IS_GOOGLE3 +#undef UPB_ATOMIC +#undef UPB_USE_C11_ATOMICS +#undef UPB_USE_MSC_ATOMICS +#undef UPB_PRIVATE +#undef UPB_ONLYBITS +#undef UPB_LINKARR_DECLARE +#undef UPB_LINKARR_APPEND +#undef UPB_LINKARR_START +#undef UPB_LINKARR_STOP +#undef UPB_FUTURE_BREAKING_CHANGES +#undef UPB_HAS_ATTRIBUTE +#undef UPB_HAS_CPP_ATTRIBUTE +#undef UPB_HAS_BUILTIN +#undef UPB_HAS_EXTENSION +#undef UPB_HAS_FEATURE +#undef UPB_XSAN_MEMBER +#undef UPB_XSAN +#undef UPB_XSAN_STRUCT_SIZE +#undef UPB_ENABLE_REF_CYCLE_CHECKS +#undef UPB_ARM64_ASM +#undef UPB_ARM64_BTI_DEFAULT +#undef UPB_DEPRECATE_AND_INLINE +#undef UPB_MAYBE_ASSUME +#undef UPB_ATTR_CONST diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c new file mode 100755 index 0000000..dd182bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.c @@ -0,0 +1,69 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby <-> upb data conversion functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#include "shared_convert.h" + +bool shared_Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + upb_CType type, const upb_MessageDef* msgdef, + upb_Status* status) { + switch (type) { + case kUpb_CType_Bool: + return memcmp(&val1, &val2, 1) == 0; + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return memcmp(&val1, &val2, 4) == 0; + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return memcmp(&val1, &val2, 8) == 0; + case kUpb_CType_String: + case kUpb_CType_Bytes: + return val1.str_val.size == val2.str_val.size && + memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) == + 0; + case kUpb_CType_Message: { + const upb_MiniTable* m = upb_MessageDef_MiniTable(msgdef); + const int options = 0; + return upb_Message_IsEqual(val1.msg_val, val2.msg_val, m, options); + } + default: + upb_Status_SetErrorMessage(status, "Internal error, unexpected type"); + return false; + } +} + +uint64_t shared_Msgval_GetHash(upb_MessageValue val, upb_CType type, + const upb_MessageDef* msgdef, uint64_t seed, + upb_Status* status) { + switch (type) { + case kUpb_CType_Bool: + return _upb_Hash(&val, 1, seed); + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + return _upb_Hash(&val, 4, seed); + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return _upb_Hash(&val, 8, seed); + case kUpb_CType_String: + case kUpb_CType_Bytes: + return _upb_Hash(val.str_val.data, val.str_val.size, seed); + case kUpb_CType_Message: + return shared_Message_Hash(val.msg_val, msgdef, seed, status); + default: + upb_Status_SetErrorMessage(status, "Internal error, unexpected type"); + return 0; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h new file mode 100755 index 0000000..ca1e91d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_convert.h @@ -0,0 +1,26 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby <-> upb data conversion functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#ifndef RUBY_PROTOBUF_SHARED_CONVERT_H_ +#define RUBY_PROTOBUF_SHARED_CONVERT_H_ + +#include "ruby-upb.h" +#include "shared_message.h" + +bool shared_Msgval_IsEqual(upb_MessageValue val1, upb_MessageValue val2, + upb_CType type, const upb_MessageDef* msgdef, + upb_Status* status); + +uint64_t shared_Msgval_GetHash(upb_MessageValue val, upb_CType type, + const upb_MessageDef* msgdef, uint64_t seed, + upb_Status* status); + +#endif // RUBY_PROTOBUF_SHARED_CONVERT_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c new file mode 100755 index 0000000..122682e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.c @@ -0,0 +1,37 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby Message functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#include "shared_message.h" + +// Support function for Message_Hash. Returns a hash value for the given +// message. +uint64_t shared_Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed, upb_Status* status) { + upb_Arena* arena = upb_Arena_New(); + char* data; + size_t size; + + // Hash a deterministically serialized payloads with no unknown fields. + upb_EncodeStatus encode_status = upb_Encode( + msg, upb_MessageDef_MiniTable(m), + kUpb_EncodeOption_SkipUnknown | kUpb_EncodeOption_Deterministic, arena, + &data, &size); + + if (encode_status == kUpb_EncodeStatus_Ok) { + uint64_t ret = _upb_Hash(data, size, seed); + upb_Arena_Free(arena); + return ret; + } + + upb_Arena_Free(arena); + upb_Status_SetErrorMessage(status, "Error calculating hash"); + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h new file mode 100755 index 0000000..5072208 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/shared_message.h @@ -0,0 +1,21 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// ----------------------------------------------------------------------------- +// Ruby Message functions. Strictly free of dependencies on +// Ruby interpreter internals. + +#ifndef RUBY_PROTOBUF_SHARED_MESSAGE_H_ +#define RUBY_PROTOBUF_SHARED_MESSAGE_H_ + +#include "ruby-upb.h" + +// Returns a hash value for the given message. +uint64_t shared_Message_Hash(const upb_Message* msg, const upb_MessageDef* m, + uint64_t seed, upb_Status* status); + +#endif // RUBY_PROTOBUF_SHARED_MESSAGE_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE new file mode 100755 index 0000000..e59f14f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2019 Yibo Cai +Copyright 2022 Google LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c new file mode 100755 index 0000000..f3301cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c @@ -0,0 +1,207 @@ +// Copyright 2023 Google LLC +// +// Use of this source code is governed by an MIT-style +// license that can be found in the LICENSE file or at +// https://opensource.org/licenses/MIT. + +/* This is a wrapper for the Google range-sse.cc algorithm which checks whether + * a sequence of bytes is a valid UTF-8 sequence and finds the longest valid + * prefix of the UTF-8 sequence. + * + * The key difference is that it checks for as much ASCII symbols as possible + * and then falls back to the range-sse.cc algorithm. The changes to the + * algorithm are cosmetic, mostly to trick the clang compiler to produce optimal + * code. + * + * For API see the utf8_validity.h header. + */ +#include "utf8_range.h" + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#if defined(__GNUC__) +#define FORCE_INLINE_ATTR __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +#define FORCE_INLINE_ATTR __forceinline +#else +#define FORCE_INLINE_ATTR inline +#endif + +static FORCE_INLINE_ATTR uint64_t utf8_range_UnalignedLoad64( + const void* p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +static FORCE_INLINE_ATTR int utf8_range_AsciiIsAscii(unsigned char c) { + return c < 128; +} + +static FORCE_INLINE_ATTR int utf8_range_IsTrailByteOk(const char c) { + return (int8_t)(c) <= (int8_t)(0xBF); +} + +/* If return_position is false then it returns 1 if |data| is a valid utf8 + * sequence, otherwise returns 0. + * If return_position is set to true, returns the length in bytes of the prefix + of |data| that is all structurally valid UTF-8. + */ +static size_t utf8_range_ValidateUTF8Naive(const char* data, const char* end, + int return_position) { + /* We return err_pos in the loop which is always 0 if !return_position */ + size_t err_pos = 0; + size_t codepoint_bytes = 0; + /* The early check is done because of early continue's on codepoints of all + * sizes, i.e. we first check for ascii and if it is, we call continue, then + * for 2 byte codepoints, etc. This is done in order to reduce indentation and + * improve readability of the codepoint validity check. + */ + while (data + codepoint_bytes < end) { + if (return_position) { + err_pos += codepoint_bytes; + } + data += codepoint_bytes; + const size_t len = end - data; + const unsigned char byte1 = data[0]; + + /* We do not skip many ascii bytes at the same time as this function is + used for tail checking (< 16 bytes) and for non x86 platforms. We also + don't think that cases where non-ASCII codepoints are followed by ascii + happen often. For small strings it also introduces some penalty. For + purely ascii UTF8 strings (which is the overwhelming case) we call + SkipAscii function which is multiplatform and extremely fast. + */ + /* [00..7F] ASCII -> 1 byte */ + if (utf8_range_AsciiIsAscii(byte1)) { + codepoint_bytes = 1; + continue; + } + /* [C2..DF], [80..BF] -> 2 bytes */ + if (len >= 2 && byte1 >= 0xC2 && byte1 <= 0xDF && + utf8_range_IsTrailByteOk(data[1])) { + codepoint_bytes = 2; + continue; + } + if (len >= 3) { + const unsigned char byte2 = data[1]; + const unsigned char byte3 = data[2]; + + /* Is byte2, byte3 between [0x80, 0xBF] + * Check for 0x80 was done above. + */ + if (!utf8_range_IsTrailByteOk(byte2) || + !utf8_range_IsTrailByteOk(byte3)) { + return err_pos; + } + + if (/* E0, A0..BF, 80..BF */ + ((byte1 == 0xE0 && byte2 >= 0xA0) || + /* E1..EC, 80..BF, 80..BF */ + (byte1 >= 0xE1 && byte1 <= 0xEC) || + /* ED, 80..9F, 80..BF */ + (byte1 == 0xED && byte2 <= 0x9F) || + /* EE..EF, 80..BF, 80..BF */ + (byte1 >= 0xEE && byte1 <= 0xEF))) { + codepoint_bytes = 3; + continue; + } + if (len >= 4) { + const unsigned char byte4 = data[3]; + /* Is byte4 between 0x80 ~ 0xBF */ + if (!utf8_range_IsTrailByteOk(byte4)) { + return err_pos; + } + + if (/* F0, 90..BF, 80..BF, 80..BF */ + ((byte1 == 0xF0 && byte2 >= 0x90) || + /* F1..F3, 80..BF, 80..BF, 80..BF */ + (byte1 >= 0xF1 && byte1 <= 0xF3) || + /* F4, 80..8F, 80..BF, 80..BF */ + (byte1 == 0xF4 && byte2 <= 0x8F))) { + codepoint_bytes = 4; + continue; + } + } + } + return err_pos; + } + if (return_position) { + err_pos += codepoint_bytes; + } + /* if return_position is false, this returns 1. + * if return_position is true, this returns err_pos. + */ + return err_pos + (1 - return_position); +} + +#if defined(__SSE4_1__) || (defined(__ARM_NEON) && defined(__ARM_64BIT_STATE)) +/* Returns the number of bytes needed to skip backwards to get to the first + byte of codepoint. + */ +static inline int utf8_range_CodepointSkipBackwards(int32_t codepoint_word) { + const int8_t* const codepoint = (const int8_t*)(&codepoint_word); + if (!utf8_range_IsTrailByteOk(codepoint[3])) { + return 1; + } else if (!utf8_range_IsTrailByteOk(codepoint[2])) { + return 2; + } else if (!utf8_range_IsTrailByteOk(codepoint[1])) { + return 3; + } + return 0; +} +#endif // __SSE4_1__ + +/* Skipping over ASCII as much as possible, per 8 bytes. It is intentional + as most strings to check for validity consist only of 1 byte codepoints. + */ +static inline const char* utf8_range_SkipAscii(const char* data, + const char* end) { + while (8 <= end - data && + (utf8_range_UnalignedLoad64(data) & 0x8080808080808080) == 0) { + data += 8; + } + while (data < end && utf8_range_AsciiIsAscii(*data)) { + ++data; + } + return data; +} + +#if defined(__SSE4_1__) +#include "utf8_range_sse.inc" +#elif defined(__ARM_NEON) && defined(__ARM_64BIT_STATE) +#include "utf8_range_neon.inc" +#endif + +static FORCE_INLINE_ATTR size_t utf8_range_Validate( + const char* data, size_t len, int return_position) { + if (len == 0) return 1 - return_position; + // Save buffer start address for later use + const char* const data_original = data; + const char* const end = data + len; + data = utf8_range_SkipAscii(data, end); + /* SIMD algorithm always outperforms the naive version for any data of + length >=16. + */ + if (end - data < 16) { + return (return_position ? (data - data_original) : 0) + + utf8_range_ValidateUTF8Naive(data, end, return_position); + } +#if defined(__SSE4_1__) || (defined(__ARM_NEON) && defined(__ARM_64BIT_STATE)) + return utf8_range_ValidateUTF8Simd( + data_original, data, end, return_position); +#else + return (return_position ? (data - data_original) : 0) + + utf8_range_ValidateUTF8Naive(data, end, return_position); +#endif +} + +bool utf8_range_IsValid(const char* data, size_t len) { + return utf8_range_Validate(data, len, /*return_position=*/0) != 0; +} + +size_t utf8_range_ValidPrefix(const char* data, size_t len) { + return utf8_range_Validate(data, len, /*return_position=*/1); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h new file mode 100755 index 0000000..5942d80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h @@ -0,0 +1,23 @@ +#ifndef THIRD_PARTY_UTF8_RANGE_UTF8_RANGE_H_ +#define THIRD_PARTY_UTF8_RANGE_UTF8_RANGE_H_ + +#include <stdbool.h> +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns 1 if the sequence of characters is a valid UTF-8 sequence, otherwise +// 0. +bool utf8_range_IsValid(const char* data, size_t len); + +// Returns the length in bytes of the prefix of str that is all +// structurally valid UTF-8. +size_t utf8_range_ValidPrefix(const char* data, size_t len); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // THIRD_PARTY_UTF8_RANGE_UTF8_RANGE_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc new file mode 100755 index 0000000..ab73754 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc @@ -0,0 +1,117 @@ +#include <arm_neon.h> + +/* This code is almost the same as SSE implementation, please reference + * utf8-range-sse.inc for detailed explanation. + * The only difference is the range adjustment step. NEON code is more + * straightforward. + */ + +static FORCE_INLINE_ATTR size_t utf8_range_ValidateUTF8Simd( + const char* data_original, const char* data, const char* end, + int return_position) { + const uint8x16_t first_len_tbl = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, + }; + const uint8x16_t first_range_tbl = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, + }; + const uint8x16_t range_min_tbl = { + 0x00, 0x80, 0x80, 0x80, 0xA0, 0x80, 0x90, 0x80, + 0xC2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + const uint8x16_t range_max_tbl = { + 0x7F, 0xBF, 0xBF, 0xBF, 0xBF, 0x9F, 0xBF, 0x8F, + 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + /* Range adjustment in NEON uint8x16x2 table. Note that lanes are interleaved + * in register. The table below is plotted vertically to ease understanding. + * The 1st column is for E0~EF, 2nd column for F0~FF. + */ + // clang-format off + const uint8_t range_adjust_tbl_data[] = { + /* index -> 0~15 16~31 <- index */ + /* E0 -> */ 2, 3, /* <- F0 */ + 0, 0, + 0, 0, + 0, 0, + 0, 4, /* <- F4 */ + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + 0, 0, + /* ED -> */ 3, 0, + 0, 0, + 0, 0, + }; + // clang-format on + const uint8x16x2_t range_adjust_tbl = vld2q_u8(range_adjust_tbl_data); + + const uint8x16_t const_1 = vdupq_n_u8(1); + const uint8x16_t const_2 = vdupq_n_u8(2); + const uint8x16_t const_e0 = vdupq_n_u8(0xE0); + + uint8x16_t prev_input = vdupq_n_u8(0); + uint8x16_t prev_first_len = vdupq_n_u8(0); + uint8x16_t error = vdupq_n_u8(0); + + while (end - data >= 16) { + const uint8x16_t input = vld1q_u8((const uint8_t*)data); + + const uint8x16_t high_nibbles = vshrq_n_u8(input, 4); + + const uint8x16_t first_len = vqtbl1q_u8(first_len_tbl, high_nibbles); + + uint8x16_t range = vqtbl1q_u8(first_range_tbl, high_nibbles); + + range = vorrq_u8(range, vextq_u8(prev_first_len, first_len, 15)); + + uint8x16_t shift2 = vextq_u8(prev_first_len, first_len, 14); + shift2 = vqsubq_u8(shift2, const_1); + range = vorrq_u8(range, shift2); + + uint8x16_t shift3 = vextq_u8(prev_first_len, first_len, 13); + shift3 = vqsubq_u8(shift3, const_2); + range = vorrq_u8(range, shift3); + + uint8x16_t shift1 = vextq_u8(prev_input, input, 15); + shift1 = vsubq_u8(shift1, const_e0); + range = vaddq_u8(range, vqtbl2q_u8(range_adjust_tbl, shift1)); + + const uint8x16_t min_range = vqtbl1q_u8(range_min_tbl, range); + const uint8x16_t max_range = vqtbl1q_u8(range_max_tbl, range); + + if (return_position) { + error = vcltq_u8(input, min_range); + error = vorrq_u8(error, vcgtq_u8(input, max_range)); + if (vmaxvq_u32(vreinterpretq_u32_u8(error))) { + break; + } + } else { + error = vorrq_u8(error, vcltq_u8(input, min_range)); + error = vorrq_u8(error, vcgtq_u8(input, max_range)); + } + + prev_input = input; + prev_first_len = first_len; + + data += 16; + } + + if (return_position && data == data_original) { + return utf8_range_ValidateUTF8Naive(data, end, return_position); + } + const int32_t prev = vgetq_lane_s32(vreinterpretq_s32_u8(prev_input), 3); + data -= utf8_range_CodepointSkipBackwards(prev); + if (return_position) { + return (data - data_original) + + utf8_range_ValidateUTF8Naive(data, end, return_position); + } + if (vmaxvq_u32(vreinterpretq_u32_u8(error))) { + return 0; + } + return utf8_range_ValidateUTF8Naive(data, end, return_position); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc new file mode 100755 index 0000000..c93fa96 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/google-protobuf-4.35.1-arm64-darwin/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc @@ -0,0 +1,272 @@ +#include <emmintrin.h> +#include <smmintrin.h> +#include <tmmintrin.h> + +static FORCE_INLINE_ATTR size_t utf8_range_ValidateUTF8Simd( + const char* data_original, const char* data, const char* end, + int return_position) { + /* This code checks that utf-8 ranges are structurally valid 16 bytes at once + * using superscalar instructions. + * The mapping between ranges of codepoint and their corresponding utf-8 + * sequences is below. + */ + + /* + * U+0000...U+007F 00...7F + * U+0080...U+07FF C2...DF 80...BF + * U+0800...U+0FFF E0 A0...BF 80...BF + * U+1000...U+CFFF E1...EC 80...BF 80...BF + * U+D000...U+D7FF ED 80...9F 80...BF + * U+E000...U+FFFF EE...EF 80...BF 80...BF + * U+10000...U+3FFFF F0 90...BF 80...BF 80...BF + * U+40000...U+FFFFF F1...F3 80...BF 80...BF 80...BF + * U+100000...U+10FFFF F4 80...8F 80...BF 80...BF + */ + + /* First we compute the type for each byte, as given by the table below. + * This type will be used as an index later on. + */ + + /* + * Index Min Max Byte Type + * 0 00 7F Single byte sequence + * 1,2,3 80 BF Second, third and fourth byte for many of the sequences. + * 4 A0 BF Second byte after E0 + * 5 80 9F Second byte after ED + * 6 90 BF Second byte after F0 + * 7 80 8F Second byte after F4 + * 8 C2 F4 First non ASCII byte + * 9..15 7F 80 Invalid byte + */ + + /* After the first step we compute the index for all bytes, then we permute + the bytes according to their indices to check the ranges from the range + table. + * The range for a given type can be found in the range_min_table and + range_max_table, the range for type/index X is in range_min_table[X] ... + range_max_table[X]. + */ + + /* Algorithm: + * Put index zero to all bytes. + * Find all non ASCII characters, give them index 8. + * For each tail byte in a codepoint sequence, give it an index corresponding + to the 1 based index from the end. + * If the first byte of the codepoint is in the [C0...DF] range, we write + index 1 in the following byte. + * If the first byte of the codepoint is in the range [E0...EF], we write + indices 2 and 1 in the next two bytes. + * If the first byte of the codepoint is in the range [F0...FF] we write + indices 3,2,1 into the next three bytes. + * For finding the number of bytes we need to look at high nibbles (4 bits) + and do the lookup from the table, it can be done with shift by 4 + shuffle + instructions. We call it `first_len`. + * Then we shift first_len by 8 bits to get the indices of the 2nd bytes. + * Saturating sub 1 and shift by 8 bits to get the indices of the 3rd bytes. + * Again to get the indices of the 4th bytes. + * Take OR of all that 4 values and check within range. + */ + /* For example: + * input C3 80 68 E2 80 20 A6 F0 A0 80 AC 20 F0 93 80 80 + * first_len 1 0 0 2 0 0 0 3 0 0 0 0 3 0 0 0 + * 1st byte 8 0 0 8 0 0 0 8 0 0 0 0 8 0 0 0 + * 2nd byte 0 1 0 0 2 0 0 0 3 0 0 0 0 3 0 0 // Shift + sub + * 3rd byte 0 0 0 0 0 1 0 0 0 2 0 0 0 0 2 0 // Shift + sub + * 4th byte 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 // Shift + sub + * Index 8 1 0 8 2 1 0 8 3 2 1 0 8 3 2 1 // OR of results + */ + + /* Checking for errors: + * Error checking is done by looking up the high nibble (4 bits) of each byte + against an error checking table. + * Because the lookup value for the second byte depends of the value of the + first byte in codepoint, we use saturated operations to adjust the index. + * Specifically we need to add 2 for E0, 3 for ED, 3 for F0 and 4 for F4 to + match the correct index. + * If we subtract from all bytes EF then EO -> 241, ED -> 254, F0 -> 1, + F4 -> 5 + * Do saturating sub 240, then E0 -> 1, ED -> 14 and we can do lookup to + match the adjustment + * Add saturating 112, then F0 -> 113, F4 -> 117, all that were > 16 will + be more 128 and lookup in ef_fe_table will return 0 but for F0 + and F4 it will be 4 and 5 accordingly + */ + /* + * Then just check the appropriate ranges with greater/smaller equal + instructions. Check tail with a naive algorithm. + * To save from previous 16 byte checks we just align previous_first_len to + get correct continuations of the codepoints. + */ + + /* + * Map high nibble of "First Byte" to legal character length minus 1 + * 0x00 ~ 0xBF --> 0 + * 0xC0 ~ 0xDF --> 1 + * 0xE0 ~ 0xEF --> 2 + * 0xF0 ~ 0xFF --> 3 + */ + const __m128i first_len_table = + _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3); + + /* Map "First Byte" to 8-th item of range table (0xC2 ~ 0xF4) */ + const __m128i first_range_table = + _mm_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8); + + /* + * Range table, map range index to min and max values + */ + const __m128i range_min_table = + _mm_setr_epi8(0x00, 0x80, 0x80, 0x80, 0xA0, 0x80, 0x90, 0x80, 0xC2, 0x7F, + 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F); + + const __m128i range_max_table = + _mm_setr_epi8(0x7F, 0xBF, 0xBF, 0xBF, 0xBF, 0x9F, 0xBF, 0x8F, 0xF4, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80); + + /* + * Tables for fast handling of four special First Bytes(E0,ED,F0,F4), after + * which the Second Byte are not 80~BF. It contains "range index adjustment". + * +------------+---------------+------------------+----------------+ + * | First Byte | original range| range adjustment | adjusted range | + * +------------+---------------+------------------+----------------+ + * | E0 | 2 | 2 | 4 | + * +------------+---------------+------------------+----------------+ + * | ED | 2 | 3 | 5 | + * +------------+---------------+------------------+----------------+ + * | F0 | 3 | 3 | 6 | + * +------------+---------------+------------------+----------------+ + * | F4 | 4 | 4 | 8 | + * +------------+---------------+------------------+----------------+ + */ + + /* df_ee_table[1] -> E0, df_ee_table[14] -> ED as ED - E0 = 13 */ + // The values represent the adjustment in the Range Index table for a correct + // index. + const __m128i df_ee_table = + _mm_setr_epi8(0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0); + + /* ef_fe_table[1] -> F0, ef_fe_table[5] -> F4, F4 - F0 = 4 */ + // The values represent the adjustment in the Range Index table for a correct + // index. + const __m128i ef_fe_table = + _mm_setr_epi8(0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + + __m128i prev_input = _mm_set1_epi8(0); + __m128i prev_first_len = _mm_set1_epi8(0); + __m128i error = _mm_set1_epi8(0); + + while (end - data >= 16) { + const __m128i input = _mm_loadu_si128((const __m128i*)(data)); + + /* high_nibbles = input >> 4 */ + const __m128i high_nibbles = + _mm_and_si128(_mm_srli_epi16(input, 4), _mm_set1_epi8(0x0F)); + + /* first_len = legal character length minus 1 */ + /* 0 for 00~7F, 1 for C0~DF, 2 for E0~EF, 3 for F0~FF */ + /* first_len = first_len_table[high_nibbles] */ + __m128i first_len = _mm_shuffle_epi8(first_len_table, high_nibbles); + + /* First Byte: set range index to 8 for bytes within 0xC0 ~ 0xFF */ + /* range = first_range_table[high_nibbles] */ + __m128i range = _mm_shuffle_epi8(first_range_table, high_nibbles); + + /* Second Byte: set range index to first_len */ + /* 0 for 00~7F, 1 for C0~DF, 2 for E0~EF, 3 for F0~FF */ + /* range |= (first_len, prev_first_len) << 1 byte */ + range = _mm_or_si128(range, _mm_alignr_epi8(first_len, prev_first_len, 15)); + + /* Third Byte: set range index to saturate_sub(first_len, 1) */ + /* 0 for 00~7F, 0 for C0~DF, 1 for E0~EF, 2 for F0~FF */ + __m128i tmp1; + __m128i tmp2; + /* tmp1 = saturate_sub(first_len, 1) */ + tmp1 = _mm_subs_epu8(first_len, _mm_set1_epi8(1)); + /* tmp2 = saturate_sub(prev_first_len, 1) */ + tmp2 = _mm_subs_epu8(prev_first_len, _mm_set1_epi8(1)); + /* range |= (tmp1, tmp2) << 2 bytes */ + range = _mm_or_si128(range, _mm_alignr_epi8(tmp1, tmp2, 14)); + + /* Fourth Byte: set range index to saturate_sub(first_len, 2) */ + /* 0 for 00~7F, 0 for C0~DF, 0 for E0~EF, 1 for F0~FF */ + /* tmp1 = saturate_sub(first_len, 2) */ + tmp1 = _mm_subs_epu8(first_len, _mm_set1_epi8(2)); + /* tmp2 = saturate_sub(prev_first_len, 2) */ + tmp2 = _mm_subs_epu8(prev_first_len, _mm_set1_epi8(2)); + /* range |= (tmp1, tmp2) << 3 bytes */ + range = _mm_or_si128(range, _mm_alignr_epi8(tmp1, tmp2, 13)); + + /* + * Now we have below range indices calculated + * Correct cases: + * - 8 for C0~FF + * - 3 for 1st byte after F0~FF + * - 2 for 1st byte after E0~EF or 2nd byte after F0~FF + * - 1 for 1st byte after C0~DF or 2nd byte after E0~EF or + * 3rd byte after F0~FF + * - 0 for others + * Error cases: + * >9 for non ascii First Byte overlapping + * E.g., F1 80 C2 90 --> 8 3 10 2, where 10 indicates error + */ + + /* Adjust Second Byte range for special First Bytes(E0,ED,F0,F4) */ + /* Overlaps lead to index 9~15, which are illegal in range table */ + __m128i shift1; + __m128i pos; + __m128i range2; + /* shift1 = (input, prev_input) << 1 byte */ + shift1 = _mm_alignr_epi8(input, prev_input, 15); + pos = _mm_sub_epi8(shift1, _mm_set1_epi8(0xEF)); + /* + * shift1: | EF F0 ... FE | FF 00 ... ... DE | DF E0 ... EE | + * pos: | 0 1 15 | 16 17 239| 240 241 255| + * pos-240: | 0 0 0 | 0 0 0 | 0 1 15 | + * pos+112: | 112 113 127| >= 128 | >= 128 | + */ + tmp1 = _mm_subs_epu8(pos, _mm_set1_epi8(-16)); + range2 = _mm_shuffle_epi8(df_ee_table, tmp1); + tmp2 = _mm_adds_epu8(pos, _mm_set1_epi8(112)); + range2 = _mm_add_epi8(range2, _mm_shuffle_epi8(ef_fe_table, tmp2)); + + range = _mm_add_epi8(range, range2); + + /* Load min and max values per calculated range index */ + __m128i min_range = _mm_shuffle_epi8(range_min_table, range); + __m128i max_range = _mm_shuffle_epi8(range_max_table, range); + + /* Check value range */ + if (return_position) { + error = _mm_cmplt_epi8(input, min_range); + error = _mm_or_si128(error, _mm_cmpgt_epi8(input, max_range)); + /* 5% performance drop from this conditional branch */ + if (!_mm_testz_si128(error, error)) { + break; + } + } else { + error = _mm_or_si128(error, _mm_cmplt_epi8(input, min_range)); + error = _mm_or_si128(error, _mm_cmpgt_epi8(input, max_range)); + } + + prev_input = input; + prev_first_len = first_len; + + data += 16; + } + /* If we got to the end, we don't need to skip any bytes backwards */ + if (return_position && data == data_original) { + return utf8_range_ValidateUTF8Naive(data, end, return_position); + } + /* Find previous codepoint (not 80~BF) */ + data -= utf8_range_CodepointSkipBackwards(_mm_extract_epi32(prev_input, 3)); + if (return_position) { + return (data - data_original) + + utf8_range_ValidateUTF8Naive(data, end, return_position); + } + /* Test if there was any error */ + if (!_mm_testz_si128(error, error)) { + return 0; + } + /* Check the tail */ + return utf8_range_ValidateUTF8Naive(data, end, return_position); +} |
