🚀 Big News:Socket Has Acquired Secure Annex.Learn More
Socket
Book a DemoSign in
Socket

protobuf

Package Overview
Dependencies
Maintainers
1
Versions
214
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

protobuf - pypi Package Compare versions

Comparing version
7.34.0
to
6.33.6
+56
upb/message/internal/tagged_ptr.h
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. 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 UPB_MINI_TABLE_INTERNAL_TAGGED_PTR_H_
#define UPB_MINI_TABLE_INTERNAL_TAGGED_PTR_H_
#include <stdint.h>
#include "upb/message/internal/message.h"
// Must be last.
#include "upb/port/def.inc"
#ifdef __cplusplus
extern "C" {
#endif
// Internal-only because empty messages cannot be created by the user.
UPB_INLINE uintptr_t
UPB_PRIVATE(_upb_TaggedMessagePtr_Pack)(struct upb_Message* ptr, bool empty) {
UPB_ASSERT(((uintptr_t)ptr & 1) == 0);
return (uintptr_t)ptr | (empty ? 1 : 0);
}
UPB_API_INLINE bool upb_TaggedMessagePtr_IsEmpty(uintptr_t ptr) {
return ptr & 1;
}
UPB_INLINE struct upb_Message* UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(
uintptr_t ptr) {
return (struct upb_Message*)(ptr & ~(uintptr_t)1);
}
UPB_API_INLINE struct upb_Message* upb_TaggedMessagePtr_GetNonEmptyMessage(
uintptr_t ptr) {
UPB_ASSERT(!upb_TaggedMessagePtr_IsEmpty(ptr));
return UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(ptr);
}
UPB_INLINE struct upb_Message* UPB_PRIVATE(
_upb_TaggedMessagePtr_GetEmptyMessage)(uintptr_t ptr) {
UPB_ASSERT(upb_TaggedMessagePtr_IsEmpty(ptr));
return UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(ptr);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_INTERNAL_TAGGED_PTR_H_ */
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. 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 UPB_MINI_TABLE_TAGGED_PTR_H_
#define UPB_MINI_TABLE_TAGGED_PTR_H_
#include <stdint.h>
#include "upb/message/internal/tagged_ptr.h"
#include "upb/message/message.h"
// Must be last.
#include "upb/port/def.inc"
// When a upb_Message* is stored in a message, array, or map, it is stored in a
// tagged form. If the tag bit is set, the referenced upb_Message is of type
// _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of
// that field's true message type. This forms the basis of what we call
// "dynamic tree shaking."
//
// See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for
// more information.
typedef uintptr_t upb_TaggedMessagePtr;
#ifdef __cplusplus
extern "C" {
#endif
// Users who enable unlinked sub-messages must use this to test whether a
// message is empty before accessing it. If a message is empty, it must be
// first promoted using the interfaces in message/promote.h.
UPB_API_INLINE bool upb_TaggedMessagePtr_IsEmpty(upb_TaggedMessagePtr ptr);
UPB_API_INLINE upb_Message* upb_TaggedMessagePtr_GetNonEmptyMessage(
upb_TaggedMessagePtr ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_TAGGED_PTR_H_ */
+1
-1

@@ -10,2 +10,2 @@ # Protocol Buffers - Google's data interchange format

__version__ = '7.34.0'
__version__ = '6.33.6'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/any.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/any.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/api.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/api.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/compiler/plugin.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/compiler/plugin.proto'

@@ -795,2 +795,13 @@ # Protocol Buffers - Google's data interchange format

@property
def label(self):
_Deprecated('label property', 'is_required or is_repeated properties')
if (
self._GetFeatures().field_presence
== _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED
):
return FieldDescriptor.LABEL_REQUIRED
return self._label
@property
def is_required(self):

@@ -797,0 +808,0 @@ """Returns if the field is required."""

@@ -22,35 +22,69 @@ /* This file was generated by upb_generator from the input file:

extern const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init;
extern const upb_MiniTable* google__protobuf__FileDescriptorSet_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__FileDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__DescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__DescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__DescriptorProto__ExtensionRange_msg_init;
extern const upb_MiniTable* google__protobuf__DescriptorProto__ExtensionRange_msg_init_ptr;
extern const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init;
extern const upb_MiniTable* google__protobuf__DescriptorProto__ReservedRange_msg_init_ptr;
extern const upb_MiniTable google__protobuf__ExtensionRangeOptions_msg_init;
extern const upb_MiniTable* google__protobuf__ExtensionRangeOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_init;
extern const upb_MiniTable* google__protobuf__ExtensionRangeOptions__Declaration_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__FieldDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__OneofDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__EnumDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__EnumDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init;
extern const upb_MiniTable* google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init_ptr;
extern const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__EnumValueDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__ServiceDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init;
extern const upb_MiniTable* google__protobuf__MethodDescriptorProto_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FileOptions_msg_init;
extern const upb_MiniTable* google__protobuf__FileOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__MessageOptions_msg_init;
extern const upb_MiniTable* google__protobuf__MessageOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FieldOptions_msg_init;
extern const upb_MiniTable* google__protobuf__FieldOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init;
extern const upb_MiniTable* google__protobuf__FieldOptions__EditionDefault_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FieldOptions__FeatureSupport_msg_init;
extern const upb_MiniTable* google__protobuf__FieldOptions__FeatureSupport_msg_init_ptr;
extern const upb_MiniTable google__protobuf__OneofOptions_msg_init;
extern const upb_MiniTable* google__protobuf__OneofOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__EnumOptions_msg_init;
extern const upb_MiniTable* google__protobuf__EnumOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__EnumValueOptions_msg_init;
extern const upb_MiniTable* google__protobuf__EnumValueOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__ServiceOptions_msg_init;
extern const upb_MiniTable* google__protobuf__ServiceOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__MethodOptions_msg_init;
extern const upb_MiniTable* google__protobuf__MethodOptions_msg_init_ptr;
extern const upb_MiniTable google__protobuf__UninterpretedOption_msg_init;
extern const upb_MiniTable* google__protobuf__UninterpretedOption_msg_init_ptr;
extern const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init;
extern const upb_MiniTable* google__protobuf__UninterpretedOption__NamePart_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FeatureSet_msg_init;
extern const upb_MiniTable* google__protobuf__FeatureSet_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FeatureSet__VisibilityFeature_msg_init;
extern const upb_MiniTable* google__protobuf__FeatureSet__VisibilityFeature_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init;
extern const upb_MiniTable* google__protobuf__FeatureSetDefaults_msg_init_ptr;
extern const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init;
extern const upb_MiniTable* google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init_ptr;
extern const upb_MiniTable google__protobuf__SourceCodeInfo_msg_init;
extern const upb_MiniTable* google__protobuf__SourceCodeInfo_msg_init_ptr;
extern const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init;
extern const upb_MiniTable* google__protobuf__SourceCodeInfo__Location_msg_init_ptr;
extern const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init;
extern const upb_MiniTable* google__protobuf__GeneratedCodeInfo_msg_init_ptr;
extern const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init;
extern const upb_MiniTable* google__protobuf__GeneratedCodeInfo__Annotation_msg_init_ptr;

@@ -57,0 +91,0 @@ extern const upb_MiniTableEnum google__protobuf__Edition_enum_init;

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/duration.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/duration.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/empty.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/empty.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/field_mask.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/field_mask.proto'

@@ -26,11 +26,2 @@ # Protocol Buffers - Google's data interchange format

def _BuildNestedDescriptors(module, msg_des, prefix):
for name, nested_msg in msg_des.nested_types_by_name.items():
module_name = prefix + name.upper()
module[module_name] = nested_msg
_BuildNestedDescriptors(module, nested_msg, module_name + '_')
for enum_des in msg_des.enum_types:
module[prefix + enum_des.name.upper()] = enum_des
def BuildMessageAndEnumDescriptors(file_des, module):

@@ -43,24 +34,17 @@ """Builds message and enum descriptors.

"""
def BuildNestedDescriptors(msg_des, prefix):
for (name, nested_msg) in msg_des.nested_types_by_name.items():
module_name = prefix + name.upper()
module[module_name] = nested_msg
BuildNestedDescriptors(nested_msg, module_name + '_')
for enum_des in msg_des.enum_types:
module[prefix + enum_des.name.upper()] = enum_des
for (name, msg_des) in file_des.message_types_by_name.items():
module_name = '_' + name.upper()
module[module_name] = msg_des
_BuildNestedDescriptors(module, msg_des, module_name + '_')
BuildNestedDescriptors(msg_des, module_name + '_')
def _BuildMessage(module_name, msg_des, prefix):
create_dict = {}
for name, nested_msg in msg_des.nested_types_by_name.items():
create_dict[name] = _BuildMessage(
module_name, nested_msg, prefix + msg_des.name + '.'
)
create_dict['DESCRIPTOR'] = msg_des
create_dict['__module__'] = module_name
create_dict['__qualname__'] = prefix + msg_des.name
message_class = _reflection.GeneratedProtocolMessageType(
msg_des.name, (_message.Message,), create_dict
)
_sym_db.RegisterMessage(message_class)
return message_class
def BuildTopDescriptorsAndMessages(file_des, module_name, module):

@@ -75,2 +59,14 @@ """Builds top level descriptors and message classes.

def BuildMessage(msg_des, prefix):
create_dict = {}
for (name, nested_msg) in msg_des.nested_types_by_name.items():
create_dict[name] = BuildMessage(nested_msg, prefix + msg_des.name + '.')
create_dict['DESCRIPTOR'] = msg_des
create_dict['__module__'] = module_name
create_dict['__qualname__'] = prefix + msg_des.name
message_class = _reflection.GeneratedProtocolMessageType(
msg_des.name, (_message.Message,), create_dict)
_sym_db.RegisterMessage(message_class)
return message_class
# top level enums

@@ -94,3 +90,3 @@ for (name, enum_des) in file_des.enum_types_by_name.items():

for (name, msg_des) in file_des.message_types_by_name.items():
module[name] = _BuildMessage(module_name, msg_des, '')
module[name] = BuildMessage(msg_des, '')

@@ -97,0 +93,0 @@

@@ -43,3 +43,2 @@ # Protocol Buffers - Google's data interchange format

from google.protobuf.descriptor import FieldDescriptor

@@ -109,3 +108,3 @@ class BaseContainer(Sequence[_T]):

# Disallows assignment to other attributes.
__slots__ = ['_type_checker', '_field']
__slots__ = ['_type_checker']

@@ -116,3 +115,2 @@ def __init__(

type_checker: Any,
field: Any = None,
) -> None:

@@ -129,3 +127,2 @@ """Args:

self._type_checker = type_checker
self._field = field

@@ -212,4 +209,3 @@ def append(self, value: _T) -> None:

clone = RepeatedScalarFieldContainer(
copy.deepcopy(self._message_listener), self._type_checker, self._field
)
copy.deepcopy(self._message_listener), self._type_checker)
clone.MergeFrom(self)

@@ -222,35 +218,3 @@ return clone

def __array__(self, dtype=None, copy=None):
import numpy as np
if dtype is None:
cpp_type = self._field.cpp_type
if cpp_type == FieldDescriptor.CPPTYPE_INT32:
dtype = np.int32
elif cpp_type == FieldDescriptor.CPPTYPE_INT64:
dtype = np.int64
elif cpp_type == FieldDescriptor.CPPTYPE_UINT32:
dtype = np.uint32
elif cpp_type == FieldDescriptor.CPPTYPE_UINT64:
dtype = np.uint64
elif cpp_type == FieldDescriptor.CPPTYPE_DOUBLE:
dtype = np.float64
elif cpp_type == FieldDescriptor.CPPTYPE_FLOAT:
dtype = np.float32
elif cpp_type == FieldDescriptor.CPPTYPE_BOOL:
dtype = np.bool
elif cpp_type == FieldDescriptor.CPPTYPE_ENUM:
dtype = np.int32
elif self._field.type == FieldDescriptor.TYPE_BYTES:
dtype = 'S'
elif self._field.type == FieldDescriptor.TYPE_STRING:
dtype = str
else:
raise SystemError(
'Code should never reach here: message type detected in'
' RepeatedScalarFieldContainer'
)
return np.array(self._values, dtype=dtype, copy=True)
# TODO: Constrain T to be a subtype of Message.

@@ -257,0 +221,0 @@ class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]):

@@ -838,3 +838,3 @@ # Protocol Buffers - Google's data interchange format

def DecodeItem(buffer, pos, end, message, field_dict, current_depth=0):
def DecodeItem(buffer, pos, end, message, field_dict):
"""Decode serialized message set to its value and new position.

@@ -892,15 +892,6 @@

extension, message_type._concrete_class())
current_depth += 1
if current_depth > _recursion_limit:
raise _DecodeError('Error parsing message: too many levels of nesting.')
if (
value._InternalParse(
buffer, message_start, message_end, current_depth
)
!= message_end
):
if value._InternalParse(buffer, message_start,message_end) != message_end:
# The only reason _InternalParse would return early is if it encountered
# an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
current_depth -= 1
else:

@@ -971,2 +962,3 @@ if not message._unknown_fields:

def DecodeMap(buffer, pos, end, message, field_dict, current_depth=0):
del current_depth # Unused.
submsg = message_type._concrete_class()

@@ -984,10 +976,6 @@ value = field_dict.get(key)

submsg.Clear()
current_depth += 1
if current_depth > _recursion_limit:
raise _DecodeError('Error parsing message: too many levels of nesting.')
if submsg._InternalParse(buffer, pos, new_pos, current_depth) != new_pos:
if submsg._InternalParse(buffer, pos, new_pos) != new_pos:
# The only reason _InternalParse would return early is if it
# encountered an end-group tag.
raise _DecodeError('Unexpected end-group tag.')
current_depth -= 1

@@ -994,0 +982,0 @@ if is_message_map:

@@ -19,3 +19,3 @@ # Protocol Buffers - Google's data interchange format

def ToJsonString(self):
"""Converts FieldMask to string according to ProtoJSON spec."""
"""Converts FieldMask to string according to proto3 JSON spec."""
camelcase_paths = []

@@ -27,3 +27,3 @@ for path in self.paths:

def FromJsonString(self, value):
"""Converts string to FieldMask according to ProtoJSON spec."""
"""Converts string to FieldMask according to proto3 JSON spec."""
if not isinstance(value, str):

@@ -30,0 +30,0 @@ raise ValueError('FieldMask JSON value not a string: {!r}'.format(value))

@@ -446,4 +446,3 @@ # Protocol Buffers - Google's data interchange format

return containers.RepeatedScalarFieldContainer(
message._listener_for_children, type_checker, field
)
message._listener_for_children, type_checker)
return MakeRepeatedScalarDefault

@@ -1245,5 +1244,3 @@

if field_decoder:
pos = field_decoder(
buffer, new_pos, end, self, field_dict, current_depth
)
pos = field_decoder(buffer, new_pos, end, self, field_dict)
continue

@@ -1250,0 +1247,0 @@ field_des, is_packed = fields_by_tag.get(tag_bytes, (None, None))

@@ -35,2 +35,6 @@ # Protocol Buffers - Google's data interchange format

_FieldDescriptor = descriptor.FieldDescriptor
# TODO: Remove this warning count after 34.0
# Assign bool to int/enum warnings will print 100 times at most which should
# be enough for users to notice and do not cause timeout.
_BoolWarningCount = 100

@@ -145,11 +149,16 @@ def TruncateToFourByteFloat(original):

def CheckValue(self, proposed_value):
if type(proposed_value) == bool:
global _BoolWarningCount
if type(proposed_value) == bool and _BoolWarningCount > 0:
_BoolWarningCount -= 1
message = (
'%.1024r has type %s, but expected one of: (int).'
'%.1024r has type %s, but expected one of: %s. This warning '
'will turn into error in 7.34.0, please fix it before that.'
% (
proposed_value,
type(proposed_value),
(int,),
)
)
raise TypeError(message)
# TODO: Raise errors in 2026 Q1 release
warnings.warn(message)

@@ -182,12 +191,16 @@ if not hasattr(proposed_value, '__index__') or (

def CheckValue(self, proposed_value):
if type(proposed_value) == bool:
global _BoolWarningCount
if type(proposed_value) == bool and _BoolWarningCount > 0:
_BoolWarningCount -= 1
message = (
'%.1024r has type %s, but expected one of: (int).'
'%.1024r has type %s, but expected one of: %s. This warning '
'will turn into error in 7.34.0, please fix it before that.'
% (
proposed_value,
type(proposed_value),
(int,),
)
)
raise TypeError(message)
# TODO: Raise errors in 2026 Q1 release
warnings.warn(message)
if not isinstance(proposed_value, numbers.Integral):

@@ -194,0 +207,0 @@ message = ('%.1024r has type %s, but expected one of: %s' %

@@ -282,9 +282,2 @@ # Protocol Buffers - Google's data interchange format

# correct transformation is calendar.timegm()
if type(dt).__name__ != 'datetime' and not isinstance(
dt, datetime.datetime
):
raise TypeError(
'Fail to convert to Timestamp. Expected a datetime object '
'got {0}'.format(type(dt).__name__)
)
try:

@@ -456,9 +449,2 @@ seconds = calendar.timegm(dt.utctimetuple())

"""Converts timedelta to Duration."""
if type(td).__name__ != 'timedelta' and not isinstance(
td, datetime.timedelta
):
raise TypeError(
'Fail to convert to Duration. Expected a timedelta object '
'got {0}'.format(type(td).__name__)
)
try:

@@ -465,0 +451,0 @@ self._NormalizeDuration(

@@ -29,2 +29,3 @@ # Protocol Buffers - Google's data interchange format

import re
import warnings

@@ -88,2 +89,3 @@ from google.protobuf import descriptor

descriptor_pool=None,
float_precision=None,
ensure_ascii=True,

@@ -110,2 +112,4 @@ always_print_fields_with_no_presence=False,

default.
float_precision: Deprecated. If set, use this to specify float field valid
digits.
ensure_ascii: If True, strings with non-ASCII characters are escaped. If

@@ -121,2 +125,3 @@ False, Unicode strings are returned unchanged.

descriptor_pool,
float_precision,
always_print_fields_with_no_presence,

@@ -133,6 +138,7 @@ )

descriptor_pool=None,
float_precision=None,
):
"""Converts protobuf message to a dictionary.
When the dictionary is encoded to JSON, it conforms to ProtoJSON spec.
When the dictionary is encoded to JSON, it conforms to proto3 JSON spec.

@@ -151,2 +157,4 @@ Args:

default.
float_precision: Deprecated. If set, use this to specify float field valid
digits.

@@ -160,2 +168,3 @@ Returns:

descriptor_pool,
float_precision,
always_print_fields_with_no_presence,

@@ -183,2 +192,3 @@ )

descriptor_pool=None,
float_precision=None,
always_print_fields_with_no_presence=False,

@@ -192,2 +202,11 @@ ):

self.descriptor_pool = descriptor_pool
if float_precision:
warnings.warn(
'float_precision option is deprecated for json_format. '
'This will turn into error in 7.34.0, please remove it '
'before that.'
)
self.float_format = '.{}g'.format(float_precision)
else:
self.float_format = None

@@ -201,3 +220,3 @@ def ToJsonString(self, message, indent, sort_keys, ensure_ascii):

def _MessageToJsonObject(self, message):
"""Converts message to an object according to ProtoJSON Specification."""
"""Converts message to an object according to Proto3 JSON Specification."""
message_descriptor = message.DESCRIPTOR

@@ -213,3 +232,3 @@ full_name = message_descriptor.full_name

def _RegularMessageToJsonObject(self, message, js):
"""Converts normal message according to ProtoJSON Specification."""
"""Converts normal message according to Proto3 JSON Specification."""
fields = message.ListFields()

@@ -280,3 +299,3 @@

def _FieldToJsonObject(self, field, value):
"""Converts field value according to ProtoJSON Specification."""
"""Converts field value according to Proto3 JSON Specification."""
if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:

@@ -318,2 +337,4 @@ return self._MessageToJsonObject(value)

return _NAN
if self.float_format:
return float(format(value, self.float_format))
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT:

@@ -325,3 +346,3 @@ return type_checkers.ToShortestFloat(value)

def _AnyMessageToJsonObject(self, message):
"""Converts Any message according to ProtoJSON Specification."""
"""Converts Any message according to Proto3 JSON Specification."""
if not message.ListFields():

@@ -348,3 +369,3 @@ return {}

def _GenericMessageToJsonObject(self, message):
"""Converts message according to ProtoJSON Specification."""
"""Converts message according to Proto3 JSON Specification."""
# Duration, Timestamp and FieldMask have ToJsonString method to do the

@@ -355,3 +376,3 @@ # convert. Users can also call the method directly.

def _ValueMessageToJsonObject(self, message):
"""Converts Value message according to ProtoJSON Specification."""
"""Converts Value message according to Proto3 JSON Specification."""
which = message.WhichOneof('kind')

@@ -382,7 +403,7 @@ # If the Value message is not set treat as null_value when serialize

def _ListValueMessageToJsonObject(self, message):
"""Converts ListValue message according to ProtoJSON Specification."""
"""Converts ListValue message according to Proto3 JSON Specification."""
return [self._ValueMessageToJsonObject(value) for value in message.values]
def _StructMessageToJsonObject(self, message):
"""Converts Struct message according to ProtoJSON Specification."""
"""Converts Struct message according to Proto3 JSON Specification."""
fields = message.fields

@@ -526,2 +547,6 @@ ret = {}

"""
# Increment recursion depth at message entry. The max_recursion_depth limit
# is exclusive: a depth value equal to max_recursion_depth will trigger an
# error. For example, with max_recursion_depth=5, nesting up to depth 4 is
# allowed, but attempting depth 5 raises ParseError.
self.recursion_depth += 1

@@ -747,8 +772,7 @@ if self.recursion_depth > self.max_recursion_depth:

elif full_name in _WKTJSONMETHODS:
methodcaller(
_WKTJSONMETHODS[full_name][1],
value['value'],
sub_message,
'{0}.value'.format(path),
)(self)
# For well-known types (including nested Any), use ConvertMessage
# to ensure recursion depth is properly tracked
self.ConvertMessage(
value['value'], sub_message, '{0}.value'.format(path)
)
else:

@@ -755,0 +779,0 @@ del value['@type']

@@ -22,13 +22,14 @@ # Protocol Buffers - Google's data interchange format

descriptor_pool: Optional[DescriptorPool]=None,
float_precision: int=None,
) -> dict:
"""Converts protobuf message to a dictionary.
When the dictionary is encoded to JSON, it conforms to ProtoJSON spec.
When the dictionary is encoded to JSON, it conforms to proto3 JSON spec.
Args:
message: The protocol buffers message instance to serialize.
always_print_fields_with_no_presence: If True, fields without presence
(implicit presence scalars, repeated fields, and map fields) will always
be serialized. Any field that supports presence is not affected by this
option (including singular message fields and oneof fields).
always_print_fields_with_no_presence: If True, fields without
presence (implicit presence scalars, repeated fields, and map fields) will
always be serialized. Any field that supports presence is not affected by
this option (including singular message fields and oneof fields).
preserving_proto_field_name: If True, use the original proto field names as

@@ -40,2 +41,3 @@ defined in the .proto file. If False, convert the field names to

default.
float_precision: If set, use this to specify float field valid digits.

@@ -50,2 +52,3 @@ Returns:

use_integers_for_enums=use_integers_for_enums,
float_precision=float_precision,
)

@@ -52,0 +55,0 @@

@@ -25,2 +25,4 @@ # Protocol Buffers - Google's data interchange format

use_index_order: bool = False,
float_format: Optional[str] = None,
double_format: Optional[str] = None,
use_field_number: bool = False,

@@ -52,2 +54,9 @@ descriptor_pool: Optional[DescriptorPool] = None,

order.
float_format (str): If set, use this to specify float field formatting (per
the "Format Specification Mini-Language"); otherwise, shortest float that
has same value in wire will be printed. Also affect double field if
double_format is not set but float_format is set.
double_format (str): If set, use this to specify double field formatting
(per the "Format Specification Mini-Language"); if it is not set but
float_format is set, use float_format. Otherwise, use ``str()``
use_field_number: If True, print field numbers instead of names.

@@ -74,2 +83,4 @@ descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types.

use_index_order=use_index_order,
float_format=float_format,
double_format=double_format,
use_field_number=use_field_number,

@@ -76,0 +87,0 @@ descriptor_pool=descriptor_pool,

@@ -30,5 +30,5 @@ # Protocol Buffers - Google's data interchange format

OSS_DOMAIN = Domain.PUBLIC
OSS_MAJOR = 7
OSS_MINOR = 34
OSS_PATCH = 0
OSS_MAJOR = 6
OSS_MINOR = 33
OSS_PATCH = 6
OSS_SUFFIX = ''

@@ -35,0 +35,0 @@

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/source_context.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/source_context.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/struct.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/struct.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/timestamp.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/timestamp.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/type.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/type.proto'

@@ -5,3 +5,3 @@ # -*- coding: utf-8 -*-

# source: google/protobuf/wrappers.proto
# Protobuf Python Version: 7.34.0
# Protobuf Python Version: 6.33.6
"""Generated protocol buffer code."""

@@ -15,5 +15,5 @@ from google.protobuf import descriptor as _descriptor

_runtime_version.Domain.PUBLIC,
7,
34,
0,
6,
33,
6,
'',

@@ -20,0 +20,0 @@ 'google/protobuf/wrappers.proto'

Metadata-Version: 2.4
Name: protobuf
Version: 7.34.0
Version: 6.33.6
Summary: Protocol Buffers

@@ -13,2 +13,3 @@ Home-page: https://developers.google.com/protocol-buffers/

Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10

@@ -18,4 +19,3 @@ Classifier: Programming Language :: Python :: 3.11

Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Requires-Python: >=3.9
License-File: LICENSE

@@ -22,0 +22,0 @@ Dynamic: classifier

Metadata-Version: 2.4
Name: protobuf
Version: 7.34.0
Version: 6.33.6
Summary: Protocol Buffers

@@ -13,2 +13,3 @@ Home-page: https://developers.google.com/protocol-buffers/

Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10

@@ -18,4 +19,3 @@ Classifier: Programming Language :: Python :: 3.11

Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Requires-Python: >=3.9
License-File: LICENSE

@@ -22,0 +22,0 @@ Dynamic: classifier

@@ -93,3 +93,2 @@ LICENSE

upb/base/descriptor_constants.h
upb/base/error_handler.h
upb/base/status.c

@@ -139,2 +138,3 @@ upb/base/status.h

upb/message/promote.h
upb/message/tagged_ptr.h
upb/message/value.h

@@ -154,2 +154,3 @@ upb/message/internal/accessors.h

upb/message/internal/message.h
upb/message/internal/tagged_ptr.h
upb/message/internal/types.h

@@ -171,4 +172,2 @@ upb/mini_descriptor/build_enum.c

upb/mini_table/compat.h
upb/mini_table/debug_string.c
upb/mini_table/debug_string.h
upb/mini_table/enum.h

@@ -180,4 +179,2 @@ upb/mini_table/extension.h

upb/mini_table/file.h
upb/mini_table/generated_registry.c
upb/mini_table/generated_registry.h
upb/mini_table/message.c

@@ -190,3 +187,2 @@ upb/mini_table/message.h

upb/mini_table/internal/file.h
upb/mini_table/internal/generated_registry.h
upb/mini_table/internal/message.c

@@ -277,3 +273,2 @@ upb/mini_table/internal/message.h

upb/wire/internal/decoder.h
upb/wire/internal/eps_copy_input_stream.h
upb/wire/internal/reader.h

@@ -280,0 +275,0 @@ utf8_range/utf8_range.c

@@ -64,8 +64,17 @@ // Protocol Buffers - Google's data interchange format

// TODO: raise error in 2026 Q1 release
static void WarnBool(const upb_FieldDef* f) {
static int bool_warning_count = 100;
if (bool_warning_count > 0) {
--bool_warning_count;
PyErr_WarnFormat(PyExc_DeprecationWarning, 3,
"Field %s: Expected an int, got a boolean. This "
"will be rejected in 7.34.0, please fix it before that",
upb_FieldDef_FullName(f));
}
}
static bool PyUpb_GetInt64(PyObject* obj, const upb_FieldDef* f, int64_t* val) {
if (PyBool_Check(obj)) {
PyErr_Format(PyExc_TypeError,
"Field %s: Expected an int, got a boolean.",
upb_FieldDef_FullName(f));
return false;
WarnBool(f);
}

@@ -93,6 +102,3 @@ // We require that the value is either an integer or has an __index__

if (PyBool_Check(obj)) {
PyErr_Format(PyExc_TypeError,
"Field %s: Expected an int, got a boolean.",
upb_FieldDef_FullName(f));
return false;
WarnBool(f);
}

@@ -198,6 +204,3 @@ // We require that the value is either an integer or has an __index__

if (PyBool_Check(obj)) {
PyErr_Format(PyExc_TypeError,
"Field %s: Expected an int, got a boolean.",
upb_FieldDef_FullName(f));
return false;
WarnBool(f);
}

@@ -204,0 +207,0 @@ int32_t i32;

@@ -15,3 +15,2 @@ // Protocol Buffers - Google's data interchange format

#include "python/protobuf.h"
#include "python/python_api.h"
#include "upb/base/upcast.h"

@@ -80,7 +79,3 @@ #include "upb/message/compare.h"

PyObject* pool = PyUpb_ObjCache_Get(symtab);
assert(pool
#if PY_VERSION_HEX >= 0x030D0000 // >= 3.13
|| Py_IsFinalizing()
#endif
);
assert(pool);
return pool;

@@ -335,3 +330,3 @@ }

"DescriptorDatabase. Add your file to the underlying database.");
return NULL;
return false;
}

@@ -349,3 +344,3 @@ return PyUpb_DescriptorPool_DoAddSerializedFile(_self, serialized_pb);

"Add your file to the underlying database.");
return NULL;
return false;
}

@@ -352,0 +347,0 @@ return PyUpb_DescriptorPool_DoAdd(_self, file_desc);

@@ -194,3 +194,3 @@ // Protocol Buffers - Google's data interchange format

}
if (!PyUpb_MapContainer_Set(self, map, u_key, u_val, arena)) return NULL;
if (!PyUpb_MapContainer_Set(self, map, u_key, u_val, arena)) return false;
}

@@ -197,0 +197,0 @@ return PyUpb_UpbToPy(u_val, val_f, self->arena);

@@ -90,3 +90,3 @@ // Protocol Buffers - Google's data interchange format

if (wkt_module == NULL) {
return NULL;
return false;
}

@@ -184,54 +184,20 @@

static PyUpb_WeakMap* PyUpb_ObjCache_MaybeInstance(void) {
// During the shutdown sequence, our objects may need to be deallocated, or
// there may even still be attempts to *construct* new ones (in user code).
// At that point our state will be NULL, so all access to the cache has to be
// no-op.
PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet();
if (!state) {
return NULL;
}
return state->obj_cache;
}
void PyUpb_ObjCache_Add(const void* key, PyObject* py_obj) {
PyUpb_WeakMap* cache = PyUpb_ObjCache_MaybeInstance();
if (!cache) {
return;
}
PyUpb_WeakMap_Add(cache, key, py_obj);
PyUpb_WeakMap_Add(PyUpb_ObjCache_Instance(), key, py_obj);
}
void PyUpb_ObjCache_Delete(const void* key) {
PyUpb_WeakMap* cache = PyUpb_ObjCache_MaybeInstance();
if (!cache) {
PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet();
if (!state) {
// During the shutdown sequence, our object's Dealloc() methods can be
// called *after* our module Dealloc() method has been called. At that
// point our state will be NULL and there is nothing to delete out of the
// map.
return;
}
PyUpb_WeakMap_Delete(cache, key);
PyUpb_WeakMap_Delete(state->obj_cache, key);
}
PyObject* PyUpb_ObjCache_Get(const void* key) {
PyUpb_WeakMap* cache = PyUpb_ObjCache_MaybeInstance();
if (!cache) {
// When the interpreter is finalizing, the state may not be available, so
// we don't try to find existing objects in the object cache - in order to
// prevent a crash. Unfortunately, doing this can lead to different
// semantics in protobuf APIs during shutdown. For example:
//
// m = MyMessage()
//
// # Returns true most of the time, but false during shutdown.
// assert(m.submsg is m.submsg)
// assert(Py_IsFinalizing());
//
//
// # Returns true most of the time, but false during shutdown.
// assert(foo_pb2.DESCRIPTOR.message_types_by_name['Bar'] is
// foo_pb2.DESCRIPTOR.message_types_by_name['Bar')
#if PY_VERSION_HEX >= 0x030D0000 // >= 3.13
assert(Py_IsFinalizing());
#endif
return NULL;
}
return PyUpb_WeakMap_Get(cache, key);
return PyUpb_WeakMap_Get(PyUpb_ObjCache_Instance(), key);
}

@@ -238,0 +204,0 @@

@@ -732,199 +732,5 @@ // Protocol Buffers - Google's data interchange format

char* GetDefaultDTypeStr(upb_CType cpp_type) {
switch (cpp_type) {
case kUpb_CType_Float:
return "f4";
case kUpb_CType_Int32:
return "i4";
case kUpb_CType_Int64:
return "i8";
case kUpb_CType_UInt32:
return "u4";
case kUpb_CType_UInt64:
return "u8";
case kUpb_CType_Double:
return "f8";
case kUpb_CType_Bool:
return "?"; // Boolean is '?' per official docs.
case kUpb_CType_Enum:
return "i4";
case kUpb_CType_String:
case kUpb_CType_Bytes:
case kUpb_CType_Message:
return NULL;
}
return NULL;
}
PyObject* CreateArrayFromView(PyObject* _self, PyObject* np_module) {
PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)(_self);
upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
size_t size = arr ? upb_Array_Size(arr) : 0;
const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
Py_ssize_t out_buffer_size_bytes;
const char* out_dtype = GetDefaultDTypeStr(upb_FieldDef_CType(f));
switch (upb_FieldDef_CType(f)) {
case kUpb_CType_Float: {
out_buffer_size_bytes = sizeof(float) * size;
break;
}
case kUpb_CType_Int32: {
out_buffer_size_bytes = 4 * size;
break;
}
case kUpb_CType_Int64: {
out_buffer_size_bytes = 8 * size;
break;
}
case kUpb_CType_UInt32: {
out_buffer_size_bytes = 4 * size;
break;
}
case kUpb_CType_UInt64: {
out_buffer_size_bytes = 8 * size;
break;
}
case kUpb_CType_Double: {
out_buffer_size_bytes = sizeof(double) * size;
break;
}
case kUpb_CType_Bool: {
out_buffer_size_bytes = sizeof(bool) * size;
break;
}
case kUpb_CType_Enum: {
out_buffer_size_bytes = 4 * size;
break;
}
case kUpb_CType_Message:
case kUpb_CType_Bytes:
case kUpb_CType_String: {
PyErr_Format(PyExc_SystemError,
"Code should never reach here: cpp type "
"should not be message nor string in CreateArrayFromView.");
return NULL;
}
}
if (out_buffer_size_bytes == 0) {
return PyObject_CallMethod(np_module, "empty", "is", 0, out_dtype);
}
const void* out_ptr = upb_Array_DataPtr(arr);
PyObject* view = PyMemoryView_FromMemory(
(char*)(const char*)out_ptr, out_buffer_size_bytes, 0x100 /*PyBUF_READ*/);
PyObject* return_value =
PyObject_CallMethod(np_module, "frombuffer", "Os", view, out_dtype);
Py_DECREF(view);
return return_value;
}
// CPython equivalent of nparray.astype(dtype_requested, copy=copy).
PyObject* NpArrayAsType(PyObject* nparray, PyObject* dtype_requested,
bool copy) {
PyObject* astype_args = Py_BuildValue("(O)", dtype_requested);
PyObject* keywords = PyDict_New();
PyDict_SetItemString(keywords, "copy", copy ? Py_True : Py_False);
PyObject* np_array_astype = PyObject_GetAttrString(nparray, "astype");
PyObject* return_value =
PyObject_Call(np_array_astype, astype_args, keywords);
Py_DECREF(np_array_astype);
Py_DECREF(keywords);
Py_DECREF(astype_args);
return return_value;
}
PyObject* ConstructArrayByIteration(PyObject* _self, PyObject* np_module) {
PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self;
upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self);
Py_ssize_t array_length = PyUpb_RepeatedContainer_Length(_self);
const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
PyObject* nparray =
PyObject_CallMethod(np_module, "empty", "is", array_length, "O");
PyObject* arena = self->arena;
for (Py_ssize_t i = 0; i < array_length; ++i) {
upb_MessageValue msgval = upb_Array_Get(arr, i);
PyObject* item = PyUpb_UpbToPy(msgval, f, arena);
PySequence_SetItem(nparray, i, item);
Py_DECREF(item);
}
return nparray;
}
static PyObject* PyUpb_RepeatedScalarContainer_AsNpArray(PyObject* _self,
PyObject* args,
PyObject* kwargs) {
static const char* kwlist[] = {"dtype", "copy", NULL};
PyObject* dtype_requested = NULL;
PyObject* copy = NULL;
PyObject* return_value = NULL;
PyObject* default_dtype = NULL;
PyObject* nparray = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", (char**)kwlist,
&dtype_requested, &copy)) {
return NULL;
}
PyObject* np_module = PyImport_ImportModule("numpy");
if (np_module == NULL) {
PyErr_Format(PyExc_ImportError, "Unable to import numpy.");
return NULL;
}
PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)(_self);
const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self);
upb_CType c_type = upb_FieldDef_CType(f);
// string repeated
if (c_type == kUpb_CType_String || c_type == kUpb_CType_Bytes) {
nparray = ConstructArrayByIteration(_self, np_module);
if (dtype_requested == NULL) {
if (c_type == kUpb_CType_String) {
dtype_requested = PyObject_CallMethod(np_module, "dtype", "s", "str");
} else {
dtype_requested = PyObject_CallMethod(np_module, "dtype", "s", "S");
}
default_dtype = dtype_requested;
}
return_value = NpArrayAsType(nparray, dtype_requested, false);
goto ret;
}
// non-string scalar repeated
if (dtype_requested == NULL) {
char* returned_dtype = GetDefaultDTypeStr(c_type);
if (returned_dtype == NULL) {
PyErr_SetString(PyExc_SystemError,
"Implementation error: Unhandled case in AsNpArray.");
return NULL;
}
if (PyUpb_RepeatedContainer_Length(_self) == 0) {
return_value =
PyObject_CallMethod(np_module, "empty", "is", 0, returned_dtype);
goto ret;
}
dtype_requested =
PyObject_CallMethod(np_module, "dtype", "s", returned_dtype);
// For ref-counting.
default_dtype = dtype_requested;
}
nparray = CreateArrayFromView(_self, np_module);
if (nparray == NULL) {
goto ret;
}
return_value = NpArrayAsType(nparray, dtype_requested, true);
ret:
Py_XDECREF(default_dtype);
Py_XDECREF(nparray);
Py_DECREF(np_module);
assert(!PyErr_Occurred());
return return_value;
}
static PyMethodDef PyUpb_RepeatedScalarContainer_Methods[] = {
{"__deepcopy__", PyUpb_RepeatedContainer_DeepCopy, METH_VARARGS,
"Makes a deep copy of the class."},
{"__array__", (PyCFunction)PyUpb_RepeatedScalarContainer_AsNpArray,
METH_VARARGS | METH_KEYWORDS, "Returns a np.array."},
{"__reduce__", PyUpb_RepeatedScalarContainer_Reduce, METH_NOARGS,

@@ -931,0 +737,0 @@ "Outputs picklable representation of the repeated field."},

@@ -12,3 +12,2 @@ // Protocol Buffers - Google's data interchange format

#include "python/protobuf.h"
#include "upb/base/string_view.h"
#include "upb/message/message.h"

@@ -88,9 +87,10 @@ #include "upb/wire/eps_copy_input_stream.h"

int size;
upb_StringView sv;
ptr = upb_WireReader_ReadSize(ptr, &size, stream);
ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(stream, ptr, size,
&sv);
if (!ptr) goto err;
if (!upb_EpsCopyInputStream_CheckDataSizeAvailable(stream, ptr, size)) {
goto err;
}
const char* str = ptr;
ptr = upb_EpsCopyInputStream_ReadStringAliased(stream, &str, size);
if (!msg) {
msg = PyBytes_FromStringAndSize(sv.data, sv.size);
msg = PyBytes_FromStringAndSize(str, size);
if (!msg) goto err;

@@ -177,8 +177,9 @@ } else {

int size;
upb_StringView sv;
ptr = upb_WireReader_ReadSize(ptr, &size, stream);
ptr =
upb_EpsCopyInputStream_ReadStringAlwaysAlias(stream, ptr, size, &sv);
if (!ptr) return NULL;
*data = PyBytes_FromStringAndSize(sv.data, sv.size);
if (!upb_EpsCopyInputStream_CheckDataSizeAvailable(stream, ptr, size)) {
return NULL;
}
const char* str = ptr;
ptr = upb_EpsCopyInputStream_ReadStringAliased(stream, &str, size);
*data = PyBytes_FromStringAndSize(str, size);
return ptr;

@@ -256,3 +257,3 @@ }

upb_EpsCopyInputStream stream;
upb_EpsCopyInputStream_Init(&stream, &ptr, view.size);
upb_EpsCopyInputStream_Init(&stream, &ptr, view.size, true);
const upb_MessageDef* msgdef = PyUpb_Message_GetMsgdef(py_msg);

@@ -259,0 +260,0 @@

@@ -74,2 +74,3 @@ #! /usr/bin/env python

'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',

@@ -79,3 +80,2 @@ 'Programming Language :: Python :: 3.11',

'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
],

@@ -93,3 +93,3 @@ packages=find_namespace_packages(include=['google*']),

],
python_requires='>=3.10',
python_requires='>=3.9',
)

@@ -39,3 +39,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/mini_table/file.h"
#include "upb/mini_table/internal/generated_registry.h"
#include "upb/mini_table/message.h"

@@ -42,0 +41,0 @@ #include "upb/mini_table/sub.h"

@@ -152,10 +152,6 @@ // Protocol Buffers - Google's data interchange format

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;
// We want to invalidate pointers to the old region if hwasan is enabled, so
// we poison and unpoison even if ptr == ret.
UPB_PRIVATE(upb_Xsan_PoisonRegion)(ptr, oldsize);
return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size);
}

@@ -162,0 +158,0 @@

@@ -20,7 +20,8 @@ // Protocol Buffers - Google's data interchange format

bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* f,
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTable* m,
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_MiniTable_MapEntrySubMessage(m, f);
UPB_ASSERT(map_entry_mini_table);

@@ -27,0 +28,0 @@ const upb_MiniTableField* map_entry_key_field =

@@ -19,2 +19,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/message/message.h"
#include "upb/message/tagged_ptr.h"
#include "upb/message/value.h"

@@ -60,2 +61,6 @@ #include "upb/mini_table/extension.h"

UPB_API_INLINE upb_TaggedMessagePtr upb_Message_GetTaggedMessagePtr(
const upb_Message* msg, const upb_MiniTableField* field,
upb_Message* default_val);
UPB_API_INLINE const upb_Array* upb_Message_GetArray(

@@ -107,3 +112,4 @@ const upb_Message* msg, const upb_MiniTableField* f);

UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage(
upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena);
upb_Message* msg, const upb_MiniTable* mini_table,
const upb_MiniTableField* f, upb_Arena* arena);

@@ -122,5 +128,5 @@ UPB_API_INLINE upb_StringView

UPB_API_INLINE void upb_Message_SetClosedEnum(upb_Message* msg,
const upb_MiniTableField* f,
int32_t value);
UPB_API_INLINE void upb_Message_SetClosedEnum(
upb_Message* msg, const upb_MiniTable* msg_mini_table,
const upb_MiniTableField* f, int32_t value);

@@ -308,3 +314,4 @@ // BaseField Setters ///////////////////////////////////////////////////////////

// Updates a map entry given an entry message.
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTableField* field,
bool upb_Message_SetMapEntry(upb_Map* map, const upb_MiniTable* mini_table,
const upb_MiniTableField* field,
upb_Message* map_entry_message, upb_Arena* arena);

@@ -316,31 +323,4 @@

#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
#include "upb/port/undef.inc"
#endif // UPB_MESSAGE_ACCESSORS_H_

@@ -76,3 +76,3 @@ // Protocol Buffers - Google's data interchange format

const upb_MiniTableField* f = upb_MiniTable_MapValue(m);
const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f);
const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(m, f);
const upb_CType ctype = upb_MiniTableField_CType(f);

@@ -113,3 +113,3 @@

const upb_MiniTable* subm = upb_MiniTable_SubMessage(f1);
const upb_MiniTable* subm = upb_MiniTable_SubMessage(m, f1);
const upb_CType ctype = upb_MiniTableField_CType(f1);

@@ -116,0 +116,0 @@

@@ -26,2 +26,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/message/message.h"
#include "upb/message/tagged_ptr.h"
#include "upb/mini_table/extension.h"

@@ -75,7 +76,10 @@ #include "upb/mini_table/field.h"

case kUpb_CType_Message: {
UPB_ASSERT(sub);
const upb_Message* source = *(upb_Message**)value;
const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value;
bool is_empty = upb_TaggedMessagePtr_IsEmpty(source);
if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)();
UPB_ASSERT(source);
upb_Message* clone = upb_Message_DeepClone(source, sub, arena);
*(upb_Message**)value = clone;
upb_Message* clone = upb_Message_DeepClone(
UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(source), sub, arena);
*(upb_TaggedMessagePtr*)value =
UPB_PRIVATE(_upb_TaggedMessagePtr_Pack)(clone, is_empty);
return clone != NULL;

@@ -102,3 +106,3 @@ } break;

upb_MiniTableField_CType(value_field) == kUpb_CType_Message
? upb_MiniTable_GetSubMessageTable(value_field)
? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field)
: NULL;

@@ -122,3 +126,4 @@ upb_CType value_field_type = upb_MiniTableField_CType(value_field);

UPB_ASSERT(!upb_Message_IsFrozen(clone));
const upb_MiniTable* map_entry_table = upb_MiniTable_MapEntrySubMessage(f);
const upb_MiniTable* map_entry_table =
upb_MiniTable_MapEntrySubMessage(mini_table, f);
UPB_ASSERT(map_entry_table);

@@ -167,8 +172,8 @@

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);
upb_Array* cloned_array = upb_Array_DeepClone(
array, upb_MiniTableField_CType(field),
upb_MiniTableField_CType(field) == kUpb_CType_Message
? upb_MiniTable_GetSubMessageTable(mini_table, field)
: NULL,
arena);

@@ -202,6 +207,14 @@ // Clear out upb_Array* due to parent memcpy.

case kUpb_CType_Message: {
const upb_Message* sub_message = upb_Message_GetMessage(src, field);
upb_TaggedMessagePtr tagged =
upb_Message_GetTaggedMessagePtr(src, field, NULL);
const upb_Message* sub_message =
UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(tagged);
if (sub_message != NULL) {
// If the message is currently in an unlinked, "empty" state we keep
// it that way, because we don't want to deal with decode options,
// decode status, or possible parse failure here.
bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged);
const upb_MiniTable* sub_message_table =
upb_MiniTable_GetSubMessageTable(field);
is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)()
: upb_MiniTable_GetSubMessageTable(mini_table, field);
upb_Message* dst_sub_message =

@@ -212,3 +225,6 @@ upb_Message_DeepClone(sub_message, sub_message_table, arena);

}
upb_Message_SetBaseFieldMessage(dst, field, dst_sub_message);
UPB_PRIVATE(_upb_Message_SetTaggedMessagePtr)
(dst, field,
UPB_PRIVATE(_upb_TaggedMessagePtr_Pack)(dst_sub_message,
is_empty));
}

@@ -281,4 +297,4 @@ } break;

// Make a copy into destination arena.
if (!UPB_PRIVATE(_upb_Message_AddUnknown)(
dst, unknown->data, unknown->size, arena, kUpb_AddUnknown_Copy)) {
if (!UPB_PRIVATE(_upb_Message_AddUnknown)(dst, unknown->data,
unknown->size, arena, NULL)) {
return NULL;

@@ -285,0 +301,0 @@ }

@@ -23,2 +23,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/message/internal/message.h"
#include "upb/message/internal/tagged_ptr.h"
#include "upb/message/internal/types.h"

@@ -420,5 +421,18 @@ #include "upb/message/value.h"

UPB_INLINE void UPB_PRIVATE(_upb_Message_AssertMapIsUntagged)(
const struct upb_Message* msg, const upb_MiniTableField* field) {
UPB_UNUSED(msg);
UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field);
#ifndef NDEBUG
uintptr_t default_val = 0;
uintptr_t tagged;
_upb_Message_GetNonExtensionField(msg, field, &default_val, &tagged);
UPB_ASSERT(!upb_TaggedMessagePtr_IsEmpty(tagged));
#endif
}
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);
UPB_PRIVATE(_upb_Message_AssertMapIsUntagged)(msg, f);
struct upb_Map* ret;

@@ -430,4 +444,5 @@ const struct upb_Map* default_val = NULL;

UPB_API_INLINE const struct upb_Message* upb_Message_GetMessage(
const struct upb_Message* msg, const upb_MiniTableField* f) {
UPB_API_INLINE uintptr_t upb_Message_GetTaggedMessagePtr(
const struct upb_Message* msg, const upb_MiniTableField* f,
struct upb_Message* default_val) {
UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message);

@@ -437,7 +452,26 @@ UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) ==

UPB_ASSUME(upb_MiniTableField_IsScalar(f));
upb_MessageValue def;
def.msg_val = NULL;
return upb_Message_GetField(msg, f, def).msg_val;
uintptr_t tagged;
_upb_Message_GetNonExtensionField(msg, f, &default_val, &tagged);
return tagged;
}
// For internal use only; users cannot set tagged messages because only the
// parser and the message copier are allowed to directly create an empty
// message.
UPB_INLINE void UPB_PRIVATE(_upb_Message_SetTaggedMessagePtr)(
struct upb_Message* msg, const upb_MiniTableField* f,
uintptr_t sub_message) {
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_Message_SetBaseField(msg, f, &sub_message);
}
UPB_API_INLINE const struct upb_Message* upb_Message_GetMessage(
const struct upb_Message* msg, const upb_MiniTableField* f) {
uintptr_t tagged = upb_Message_GetTaggedMessagePtr(msg, f, NULL);
return upb_TaggedMessagePtr_GetNonEmptyMessage(tagged);
}
UPB_API_INLINE upb_Array* upb_Message_GetMutableArray(

@@ -480,2 +514,3 @@ struct upb_Message* msg, const upb_MiniTableField* f) {

UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field);
UPB_PRIVATE(_upb_Message_AssertMapIsUntagged)(msg, field);
struct upb_Map* map = NULL;

@@ -508,3 +543,4 @@ struct upb_Map* default_map_value = NULL;

UPB_API_INLINE struct upb_Message* upb_Message_GetOrCreateMutableMessage(
struct upb_Message* msg, const upb_MiniTableField* f, upb_Arena* arena) {
struct upb_Message* msg, const upb_MiniTable* mini_table,
const upb_MiniTableField* f, upb_Arena* arena) {
UPB_ASSERT(arena);

@@ -516,3 +552,4 @@ UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message);

if (!sub_message) {
const upb_MiniTable* sub_mini_table = upb_MiniTable_SubMessage(f);
const upb_MiniTable* sub_mini_table =
upb_MiniTable_SubMessage(mini_table, f);
UPB_ASSERT(sub_mini_table);

@@ -615,8 +652,4 @@ sub_message = _upb_Message_New(sub_mini_table, arena);

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_PRIVATE(_upb_Message_SetTaggedMessagePtr)
(msg, f, UPB_PRIVATE(_upb_TaggedMessagePtr_Pack)(value, false));
}

@@ -654,2 +687,3 @@

UPB_API_INLINE void upb_Message_SetClosedEnum(struct upb_Message* msg,
const upb_MiniTable* m,
const upb_MiniTableField* f,

@@ -659,4 +693,4 @@ int32_t value) {

UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == kUpb_FieldRep_4Byte);
UPB_ASSERT(upb_MiniTableEnum_CheckValue(upb_MiniTable_GetSubEnumTable(f),
(uint32_t)value));
UPB_ASSERT(
upb_MiniTableEnum_CheckValue(upb_MiniTable_GetSubEnumTable(m, f), value));
upb_Message_SetBaseField(msg, f, &value);

@@ -663,0 +697,0 @@ }

@@ -180,10 +180,10 @@ // Protocol Buffers - Google's data interchange format

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);
const char* s_ptr = ptr;
ptr = upb_EpsCopyInputStream_ReadStringAliased(&ctx->stream, &s_ptr,
size);
UPB_ASSERT(ptr);
field->data.delimited.data = sv.data;
field->data.delimited.size = sv.size;
field->data.delimited.data = s_ptr;
field->data.delimited.size = size;
break;

@@ -255,3 +255,3 @@ }

while (upb_Message_NextUnknown(msg, &view, &iter)) {
upb_EpsCopyInputStream_Init(&ctx->stream, &view.data, view.size);
upb_EpsCopyInputStream_Init(&ctx->stream, &view.data, view.size, true);
upb_CombineUnknownFields(ctx, &builder, &view.data);

@@ -258,0 +258,0 @@ UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &view.data) &&

@@ -49,19 +49,2 @@ // Protocol Buffers - Google's data interchange format

// 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;

@@ -168,14 +151,2 @@ } upb_TaggedAuxPtr;

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

@@ -195,5 +166,5 @@ // must represent one or more complete and well formed proto fields.

upb_Arena* arena,
upb_AddUnknownMode mode) {
const char* alias_base) {
UPB_ASSERT(!upb_Message_IsFrozen(msg));
if (mode == kUpb_AddUnknown_AliasAllowMerge) {
if (alias_base) {
// Aliasing parse of a message with sequential unknown fields is a simple

@@ -207,9 +178,8 @@ // pointer bump, so inline it.

// 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) {
// added unknown field. However, we could be merging into an existing
// message with an allocation that just happens to be positioned
// immediately after the previous merged unknown field; this is
// considered out-of-bounds and thus UB. Ensure it's in-bounds by
// comparing with the original input pointer for our buffer.
if (data != alias_base && existing->data + existing->size == data) {
existing->size += len;

@@ -221,4 +191,4 @@ return true;

}
return UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(
msg, data, len, arena, mode != kUpb_AddUnknown_Copy);
return UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(msg, data, len, arena,
alias_base != NULL);
}

@@ -225,0 +195,0 @@

@@ -254,3 +254,3 @@ // Protocol Buffers - Google's data interchange format

const upb_MiniTableField* f = upb_MiniTable_GetFieldByIndex(m, i);
const upb_MiniTable* m2 = upb_MiniTable_SubMessage(f);
const upb_MiniTable* m2 = upb_MiniTable_SubMessage(m, f);

@@ -267,3 +267,3 @@ switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) {

const upb_MiniTableField* f2 = upb_MiniTable_MapValue(m2);
const upb_MiniTable* m3 = upb_MiniTable_SubMessage(f2);
const upb_MiniTable* m3 = upb_MiniTable_SubMessage(m2, f2);
upb_Map_Freeze(map, m3);

@@ -270,0 +270,0 @@ }

@@ -22,4 +22,6 @@ // Protocol Buffers - Google's data interchange format

#include "upb/message/internal/message.h"
#include "upb/message/internal/tagged_ptr.h"
#include "upb/message/map.h"
#include "upb/message/message.h"
#include "upb/message/tagged_ptr.h"
#include "upb/mini_table/extension.h"

@@ -91,3 +93,3 @@ #include "upb/mini_table/field.h"

upb_EpsCopyInputStream stream;
upb_EpsCopyInputStream_Init(&stream, &ptr, data.size);
upb_EpsCopyInputStream_Init(&stream, &ptr, data.size, true);
while (!upb_EpsCopyInputStream_IsDone(&stream, &ptr)) {

@@ -99,13 +101,14 @@ uint32_t tag;

if (field_number == upb_WireReader_GetFieldNumber(tag)) {
upb_StringView data;
found_count++;
upb_EpsCopyInputStream_StartCapture(&stream, unknown_begin);
const char* start =
upb_EpsCopyInputStream_GetAliasedPtr(&stream, unknown_begin);
ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, &stream);
if (!ptr || !upb_EpsCopyInputStream_EndCapture(&stream, ptr, &data)) {
return kUpb_GetExtension_ParseError;
}
if (!ptr) return kUpb_GetExtension_ParseError;
// Because we know that the input is a flat buffer, it is safe to
// perform pointer arithmetic on aliased pointers.
size_t len = upb_EpsCopyInputStream_GetAliasedPtr(&stream, ptr) - start;
upb_UnknownToMessageRet parse_result =
upb_MiniTable_ParseUnknownMessage(
data.data, data.size, extension_table,
/* base_message= */ extension_msg, decode_options, arena);
upb_MiniTable_ParseUnknownMessage(start, len, extension_table,
/* base_message= */ extension_msg,
decode_options, arena);
switch (parse_result.status) {

@@ -166,3 +169,3 @@ case kUpb_UnknownToMessage_OutOfMemory:

const char* ptr = data.data;
upb_EpsCopyInputStream_Init(&stream, &ptr, data.size);
upb_EpsCopyInputStream_Init(&stream, &ptr, data.size, true);

@@ -175,11 +178,8 @@ while (!upb_EpsCopyInputStream_IsDone(&stream, &ptr)) {

if (field_number == upb_WireReader_GetFieldNumber(tag)) {
upb_StringView data;
ret.status = kUpb_FindUnknown_Ok;
upb_EpsCopyInputStream_StartCapture(&stream, unknown_begin);
ret.ptr = upb_EpsCopyInputStream_GetAliasedPtr(&stream, unknown_begin);
ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, &stream);
if (!ptr || !upb_EpsCopyInputStream_EndCapture(&stream, ptr, &data)) {
return upb_FindUnknownRet_ParseError();
}
ret.ptr = data.data;
ret.len = data.size;
// Because we know that the input is a flat buffer, it is safe to
// perform pointer arithmetic on aliased pointers.
ret.len = upb_EpsCopyInputStream_GetAliasedPtr(&stream, ptr) - ret.ptr;
return ret;

@@ -199,2 +199,82 @@ }

static upb_DecodeStatus upb_Message_PromoteOne(upb_TaggedMessagePtr* tagged,
const upb_MiniTable* mini_table,
int decode_options,
upb_Arena* arena) {
upb_Message* empty =
UPB_PRIVATE(_upb_TaggedMessagePtr_GetEmptyMessage)(*tagged);
upb_Message* promoted = upb_Message_New(mini_table, arena);
if (!promoted) return kUpb_DecodeStatus_OutOfMemory;
upb_StringView unknown_data;
uintptr_t iter = kUpb_Message_UnknownBegin;
while (upb_Message_NextUnknown(empty, &unknown_data, &iter)) {
upb_DecodeStatus status =
upb_Decode(unknown_data.data, unknown_data.size, promoted, mini_table,
NULL, decode_options, arena);
if (status != kUpb_DecodeStatus_Ok) {
return status;
}
}
*tagged = UPB_PRIVATE(_upb_TaggedMessagePtr_Pack)(promoted, false);
return kUpb_DecodeStatus_Ok;
}
upb_DecodeStatus upb_Message_PromoteMessage(upb_Message* parent,
const upb_MiniTable* mini_table,
const upb_MiniTableField* field,
int decode_options,
upb_Arena* arena,
upb_Message** promoted) {
UPB_ASSERT(!upb_Message_IsFrozen(parent));
const upb_MiniTable* sub_table =
upb_MiniTable_GetSubMessageTable(mini_table, field);
UPB_ASSERT(sub_table);
upb_TaggedMessagePtr tagged =
upb_Message_GetTaggedMessagePtr(parent, field, NULL);
upb_DecodeStatus ret =
upb_Message_PromoteOne(&tagged, sub_table, decode_options, arena);
if (ret == kUpb_DecodeStatus_Ok) {
*promoted = upb_TaggedMessagePtr_GetNonEmptyMessage(tagged);
upb_Message_SetMessage(parent, field, *promoted);
}
return ret;
}
upb_DecodeStatus upb_Array_PromoteMessages(upb_Array* arr,
const upb_MiniTable* mini_table,
int decode_options,
upb_Arena* arena) {
void** data = upb_Array_MutableDataPtr(arr);
size_t size = upb_Array_Size(arr);
for (size_t i = 0; i < size; i++) {
upb_TaggedMessagePtr tagged;
memcpy(&tagged, &data[i], sizeof(tagged));
if (!upb_TaggedMessagePtr_IsEmpty(tagged)) continue;
upb_DecodeStatus status =
upb_Message_PromoteOne(&tagged, mini_table, decode_options, arena);
if (status != kUpb_DecodeStatus_Ok) return status;
memcpy(&data[i], &tagged, sizeof(tagged));
}
return kUpb_DecodeStatus_Ok;
}
upb_DecodeStatus upb_Map_PromoteMessages(upb_Map* map,
const upb_MiniTable* mini_table,
int decode_options, upb_Arena* arena) {
size_t iter = kUpb_Map_Begin;
upb_MessageValue key, val;
while (upb_Map_Next(map, &key, &val, &iter)) {
if (!upb_TaggedMessagePtr_IsEmpty(val.tagged_msg_val)) continue;
upb_DecodeStatus status = upb_Message_PromoteOne(
&val.tagged_msg_val, mini_table, decode_options, arena);
if (status != kUpb_DecodeStatus_Ok) return status;
upb_Map_SetEntryValue(map, iter, val);
}
return kUpb_DecodeStatus_Ok;
}
////////////////////////////////////////////////////////////////////////////////
// OLD promotion functions, will be removed!
////////////////////////////////////////////////////////////////////////////////
// Warning: See TODO

@@ -211,3 +291,4 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage(

// PromotoUnknownToMessage.
UPB_ASSERT(upb_MiniTable_GetSubMessageTable(field) == sub_mini_table);
UPB_ASSERT(upb_MiniTable_GetSubMessageTable(mini_table, field) ==
sub_mini_table);
bool is_oneof = upb_MiniTableField_IsInOneof(field);

@@ -309,3 +390,3 @@ if (!is_oneof || UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, field) ==

const upb_MiniTable* map_entry_mini_table =
upb_MiniTable_MapEntrySubMessage(field);
upb_MiniTable_MapEntrySubMessage(mini_table, field);
UPB_ASSERT(upb_MiniTable_FieldCount(map_entry_mini_table) == 2);

@@ -327,4 +408,4 @@ // Find all unknowns with given field number and parse.

upb_Message* map_entry_message = ret.message;
bool insert_success =
upb_Message_SetMapEntry(map, field, map_entry_message, arena);
bool insert_success = upb_Message_SetMapEntry(map, mini_table, field,
map_entry_message, arena);
if (!insert_success) return kUpb_UnknownToMessage_OutOfMemory;

@@ -331,0 +412,0 @@ upb_StringView del =

@@ -11,12 +11,6 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include <stdint.h>
#include "upb/mem/arena.h"
#include "upb/message/array.h"
#include "upb/message/message.h"
#include "upb/message/map.h"
#include "upb/message/value.h"
#include "upb/mini_table/extension.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/message.h"
#include "upb/wire/decode.h"

@@ -84,2 +78,45 @@ // Must be last.

// Promotes an "empty" non-repeated message field in `parent` to a message of
// the correct type.
//
// Preconditions:
//
// 1. The message field must currently be in the "empty" state (this must have
// been previously verified by the caller by calling
// `upb_Message_GetTaggedMessagePtr()` and observing that the message is
// indeed empty).
//
// 2. This `field` must have previously been linked.
//
// If the promotion succeeds, `parent` will have its data for `field` replaced
// by the promoted message, which is also returned in `*promoted`. If the
// return value indicates an error status, `parent` and `promoted` are
// unchanged.
upb_DecodeStatus upb_Message_PromoteMessage(upb_Message* parent,
const upb_MiniTable* mini_table,
const upb_MiniTableField* field,
int decode_options,
upb_Arena* arena,
upb_Message** promoted);
// Promotes any "empty" messages in this array to a message of the correct type
// `mini_table`. This function should only be called for arrays of messages.
//
// If the return value indicates an error status, some but not all elements may
// have been promoted, but the array itself will not be corrupted.
upb_DecodeStatus upb_Array_PromoteMessages(upb_Array* arr,
const upb_MiniTable* mini_table,
int decode_options,
upb_Arena* arena);
// Promotes any "empty" entries in this map to a message of the correct type
// `mini_table`. This function should only be called for maps that have a
// message type as the map value.
//
// If the return value indicates an error status, some but not all elements may
// have been promoted, but the map itself will not be corrupted.
upb_DecodeStatus upb_Map_PromoteMessages(upb_Map* map,
const upb_MiniTable* mini_table,
int decode_options, upb_Arena* arena);
// Utility function for wrapper languages to get an error string from a

@@ -89,2 +126,6 @@ // upb_UnknownToMessageStatus.

////////////////////////////////////////////////////////////////////////////////
// OLD promotion interfaces, will be removed!
////////////////////////////////////////////////////////////////////////////////
// Promotes unknown data inside message to a upb_Message parsing the unknown.

@@ -91,0 +132,0 @@ //

@@ -40,2 +40,8 @@ // Protocol Buffers - Google's data interchange format

// EXPERIMENTAL: A tagged upb_Message*. Users must use this instead of
// msg_val if unlinked sub-messages may possibly be in use. See the
// documentation in kUpb_DecodeOption_ExperimentalAllowUnlinked for more
// information.
uintptr_t tagged_msg_val; // upb_TaggedMessagePtr
// For an extension field, we are essentially treating ext->data (a

@@ -42,0 +48,0 @@ // upb_MessageValue) as if it were a message with one field that lives at

@@ -11,3 +11,2 @@ // Protocol Buffers - Google's data interchange format

#include <inttypes.h>
#include <stdalign.h>
#include <stddef.h>

@@ -94,3 +93,2 @@ #include <stdint.h>

uint16_t rep_counts_offsets[kUpb_FieldRep_Max + 1];
uint32_t sub_count;
bool is_extension;

@@ -125,5 +123,5 @@

static void upb_MiniTable_SetTypeAndSub(upb_MtDecoder* d,
upb_MiniTableField* field,
static void upb_MiniTable_SetTypeAndSub(upb_MiniTableField* field,
upb_FieldType type,
upb_SubCounts* sub_counts,
uint64_t msg_modifiers,

@@ -148,9 +146,10 @@ bool is_proto3_enum) {

// 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++;
if (type == kUpb_FieldType_Message || type == kUpb_FieldType_Group) {
field->UPB_PRIVATE(submsg_index) = sub_counts->submsg_count++;
} else if (type == kUpb_FieldType_Enum) {
// We will need to update this later once we know the total number of
// submsg fields.
field->UPB_PRIVATE(submsg_index) = sub_counts->subenum_count++;
} else {
field->UPB_PRIVATE(submsg_ofs) = kUpb_NoSub;
field->UPB_PRIVATE(submsg_index) = kUpb_NoSub;
}

@@ -183,3 +182,4 @@ }

upb_MiniTableField* field,
uint64_t msg_modifiers) {
uint64_t msg_modifiers,
upb_SubCounts* sub_counts) {
static const char kUpb_EncodedToFieldRep[] = {

@@ -230,4 +230,4 @@ [kUpb_EncodedType_Double] = kUpb_FieldRep_8Byte,

}
upb_MiniTable_SetTypeAndSub(d, field, kUpb_EncodedToType[type], msg_modifiers,
type == kUpb_EncodedType_OpenEnum);
upb_MiniTable_SetTypeAndSub(field, kUpb_EncodedToType[type], sub_counts,
msg_modifiers, type == kUpb_EncodedType_OpenEnum);
}

@@ -443,29 +443,35 @@

size_t upb_MtDecoder_PtrSize(upb_MtDecoder* d) {
return d->platform == kUpb_MiniTablePlatform_32Bit ? 4 : 8;
static void* upb_MtDecoder_CheckedMalloc(upb_MtDecoder* d, size_t size) {
void* ptr = upb_Arena_Malloc(d->arena, size);
upb_MdDecoder_CheckOutOfMemory(&d->base, ptr);
return ptr;
}
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");
upb_SubCounts sub_counts) {
uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count;
size_t subs_bytes = sizeof(*d->table.UPB_PRIVATE(subs)) * total_count;
size_t ptrs_bytes = sizeof(upb_MiniTable*) * sub_counts.submsg_count;
upb_MiniTableSubInternal* subs =
subs_bytes ? upb_MtDecoder_CheckedMalloc(d, subs_bytes) : NULL;
const upb_MiniTable** subs_ptrs =
ptrs_bytes ? upb_MtDecoder_CheckedMalloc(d, ptrs_bytes) : NULL;
uint32_t i = 0;
for (; i < sub_counts.submsg_count; i++) {
subs_ptrs[i] = UPB_PRIVATE(_upb_MiniTable_Empty)();
subs[i].UPB_PRIVATE(submsg) = &subs_ptrs[i];
}
if (sub_counts.subenum_count) {
upb_MiniTableField* f = d->fields;
upb_MiniTableField* end_f = f + d->table.UPB_PRIVATE(field_count);
for (; f < end_f; f++) {
if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) {
f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count;
}
}
f->UPB_PRIVATE(submsg_ofs) = u32_ofs;
ofs += ptr_size;
for (; i < sub_counts.submsg_count + sub_counts.subenum_count; i++) {
subs[i].UPB_PRIVATE(subenum) = NULL;
}
}
d->table.UPB_PRIVATE(subs) = subs;
}

@@ -475,4 +481,4 @@

size_t len, void* fields,
size_t field_size,
uint16_t* field_count) {
size_t field_size, uint16_t* field_count,
upb_SubCounts* sub_counts) {
uint64_t msg_modifiers = 0;

@@ -502,3 +508,3 @@ uint32_t last_field_number = 0;

last_field = field;
upb_MiniTable_SetField(d, ch, field, msg_modifiers);
upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_counts);
} else if (kUpb_EncodedValue_MinModifier <= ch &&

@@ -541,38 +547,20 @@ ch <= kUpb_EncodedValue_MaxModifier) {

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");
if (SIZE_MAX / sizeof(*d->fields) < len) {
upb_MdDecoder_ErrorJmp(&d->base, "Out of memory");
}
// 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);
d->fields = upb_Arena_Malloc(d->arena, sizeof(*d->fields) * len);
upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields);
upb_SubCounts sub_counts = {0, 0};
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);
&d->table.UPB_PRIVATE(field_count), &sub_counts);
// 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);
upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
sizeof(*d->fields) * d->table.UPB_PRIVATE(field_count));
d->table.UPB_PRIVATE(fields) = d->fields;
upb_MtDecoder_AllocateSubs(d, sub_counts);
}

@@ -636,3 +624,3 @@

}
if (last_hasbit >= kUpb_Reserved_Hasbits + 63) {
if (last_hasbit > kUpb_Reserved_Hasbits + 63) {
upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields");

@@ -643,3 +631,2 @@ }

last_hasbit - (kUpb_Reserved_Hasbits - 1);
UPB_ASSERT(d->table.UPB_PRIVATE(required_count) < 64);

@@ -861,3 +848,2 @@ // Next assign non-required hasbit fields.

.platform = platform,
.sub_count = 0,
.is_extension = false,

@@ -896,4 +882,5 @@ .oneofs =

uint16_t count = 0;
const char* ret =
upb_MtDecoder_Parse(decoder, data, len, ext, sizeof(*ext), &count);
upb_SubCounts sub_counts = {0, 0};
const char* ret = upb_MtDecoder_Parse(decoder, data, len, ext, sizeof(*ext),
&count, &sub_counts);
if (!ret || count != 1) return NULL;

@@ -907,8 +894,2 @@

// 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) {

@@ -947,3 +928,2 @@ // Extensions of MessageSet must be messages.

.platform = platform,
.sub_count = 0,
.is_extension = true,

@@ -950,0 +930,0 @@ };

@@ -57,9 +57,8 @@ // Protocol Buffers - Google's data interchange format

upb_MiniTableSubInternal* table_sub =
UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes,
upb_MiniTableSubInternal);
int idx = field->UPB_PRIVATE(submsg_index);
upb_MiniTableSubInternal* table_subs = (void*)table->UPB_PRIVATE(subs);
// 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;
// UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg));
memcpy((void*)table_subs[idx].UPB_PRIVATE(submsg), &sub, sizeof(void*));
return true;

@@ -90,5 +89,4 @@ }

upb_MiniTableSubInternal* table_sub =
UPB_PTR_AT(field, field->UPB_PRIVATE(submsg_ofs) * kUpb_SubmsgOffsetBytes,
upb_MiniTableSubInternal);
upb_MiniTableSub* table_sub =
(void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)];
*table_sub = upb_MiniTableSub_FromEnum(sub);

@@ -95,0 +93,0 @@ return true;

@@ -51,4 +51,4 @@ // Protocol Buffers - Google's data interchange format

if (src_field->presence != dst_field->presence) return false;
if (src_field->UPB_PRIVATE(submsg_ofs) !=
dst_field->UPB_PRIVATE(submsg_ofs))
if (src_field->UPB_PRIVATE(submsg_index) !=
dst_field->UPB_PRIVATE(submsg_index))
return kUpb_MiniTableEquals_NotEqual;

@@ -75,5 +75,5 @@

const upb_MiniTable* sub_src =
upb_MiniTable_GetSubMessageTable(src_field);
upb_MiniTable_GetSubMessageTable(src, src_field);
const upb_MiniTable* sub_dst =
upb_MiniTable_GetSubMessageTable(dst_field);
upb_MiniTable_GetSubMessageTable(dst, dst_field);
if (sub_src != NULL) {

@@ -80,0 +80,0 @@ upb_value cmp;

@@ -92,2 +92,22 @@ // Protocol Buffers - Google's data interchange format

#ifdef UPB_LINKARR_DECLARE
UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension);
bool upb_ExtensionRegistry_AddAllLinkedExtensions(upb_ExtensionRegistry* r) {
const upb_MiniTableExtension* start = UPB_LINKARR_START(upb_AllExts);
const upb_MiniTableExtension* stop = UPB_LINKARR_STOP(upb_AllExts);
for (const upb_MiniTableExtension* p = start; p < stop; p++) {
// Windows can introduce zero padding, so we have to skip zeroes.
if (upb_MiniTableExtension_Number(p) != 0) {
if (upb_ExtensionRegistry_Add(r, p) != kUpb_ExtensionRegistryStatus_Ok) {
return false;
}
}
}
return true;
}
#endif // UPB_LINKARR_DECLARE
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(

@@ -94,0 +114,0 @@ const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {

@@ -82,2 +82,19 @@ // Protocol Buffers - Google's data interchange format

#ifdef UPB_LINKARR_DECLARE
// Adds all extensions linked into the binary into the registry. The set of
// linked extensions is assembled by the linker using linker arrays. This
// will likely not work properly if the extensions are split across multiple
// shared libraries.
//
// Returns true if all extensions were added successfully, false on out of
// memory or if any extensions were already present.
//
// This API is currently not available on MSVC (though it *is* available on
// Windows using clang-cl).
UPB_API bool upb_ExtensionRegistry_AddAllLinkedExtensions(
upb_ExtensionRegistry* r);
#endif // UPB_LINKARR_DECLARE
// Looks up the extension (if any) defined for message type |t| and field

@@ -84,0 +101,0 @@ // number |num|. Returns the extension if found, otherwise NULL.

@@ -25,4 +25,4 @@ // Protocol Buffers - Google's data interchange format

const struct upb_MiniTable* UPB_PRIVATE(extendee);
union upb_MiniTableSub UPB_PRIVATE(sub); // NULL unless submsg or proto2 enum
const struct upb_MiniTable* UPB_PRIVATE(extendee);
};

@@ -85,3 +85,3 @@

UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTableExtension_ToField(
UPB_API_INLINE const upb_MiniTableField* upb_MiniTableExtension_ToField(
const struct upb_MiniTableExtension* e) {

@@ -88,0 +88,0 @@ return &e->UPB_PRIVATE(field);

@@ -26,6 +26,5 @@ // Protocol Buffers - Google's data interchange format

// Offset from this upb_MiniTableField to the upb_MiniTableSubInternal
// for this field, in uint32_t units (so bytes/4).
// Indexes into `upb_MiniTable.subs`
// Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM
uint16_t UPB_PRIVATE(submsg_ofs);
uint16_t UPB_PRIVATE(submsg_index);

@@ -39,3 +38,2 @@ uint8_t UPB_PRIVATE(descriptortype);

#define kUpb_NoSub ((uint16_t)-1)
#define kUpb_SubmsgOffsetBytes 4

@@ -42,0 +40,0 @@ typedef enum {

@@ -17,2 +17,19 @@ // Protocol Buffers - Google's data interchange format

// A MiniTable for an empty message, used for unlinked sub-messages that are
// built via MiniDescriptors. Messages that use this MiniTable may possibly
// be linked later, in which case this MiniTable will be replaced with a real
// one. This pattern is known as "dynamic tree shaking", and it introduces
// complication because sub-messages may either be the "empty" type or the
// "real" type. A tagged bit indicates the difference.
const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = {
.UPB_PRIVATE(subs) = NULL,
.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,
};
// A MiniTable for a statically tree shaken message. Messages that use this

@@ -23,2 +40,3 @@ // MiniTable are guaranteed to remain unlinked; unlike the empty message, this

const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_StaticallyTreeShaken) = {
.UPB_PRIVATE(subs) = NULL,
.UPB_PRIVATE(fields) = NULL,

@@ -25,0 +43,0 @@ .UPB_PRIVATE(size) = sizeof(struct upb_Message),

@@ -55,2 +55,3 @@ // Protocol Buffers - Google's data interchange format

struct upb_MiniTable {
const upb_MiniTableSubInternal* UPB_PRIVATE(subs);
const struct upb_MiniTableField* UPB_ONLYBITS(fields);

@@ -103,2 +104,8 @@

UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
return &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
UPB_API_INLINE int upb_MiniTable_FieldCount(const struct upb_MiniTable* m) {

@@ -156,44 +163,54 @@ return m->UPB_ONLYBITS(field_count);

UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
const struct upb_MiniTable* m) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
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_INLINE const struct upb_MiniTable* UPB_PRIVATE(
_upb_MiniTable_GetSubTableByIndex)(const struct upb_MiniTable* m,
uint32_t i) {
return *m->UPB_PRIVATE(subs)[i].UPB_PRIVATE(submsg);
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_SubMessage(
const struct upb_MiniTableField* f) {
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
if (upb_MiniTableField_CType(f) != kUpb_CType_Message) {
return NULL;
}
return upb_MiniTable_GetSubMessageTable(f);
return UPB_PRIVATE(_upb_MiniTable_GetSubTableByIndex)(
m, f->UPB_PRIVATE(submsg_index));
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTable_GetSubMessageTable(
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message);
const struct upb_MiniTable* ret = upb_MiniTable_SubMessage(m, f);
UPB_ASSUME(ret);
return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret;
}
UPB_API_INLINE bool upb_MiniTable_FieldIsLinked(
const struct upb_MiniTableField* f) {
return upb_MiniTable_GetSubMessageTable(f) != NULL;
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
return upb_MiniTable_GetSubMessageTable(m, 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);
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
UPB_ASSERT(upb_MiniTable_FieldIsLinked(m, f)); // Map entries must be linked.
UPB_ASSERT(upb_MiniTableField_IsMap(f)); // Function precondition.
return upb_MiniTable_SubMessage(m, f);
}
UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable(
const struct upb_MiniTableField* f) {
const struct upb_MiniTable* m, 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);
return m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(
subenum);
}

@@ -200,0 +217,0 @@

@@ -14,2 +14,7 @@ // Protocol Buffers - Google's data interchange format

typedef union {
const struct upb_MiniTable* const* UPB_PRIVATE(submsg);
const struct upb_MiniTableEnum* UPB_PRIVATE(subenum);
} upb_MiniTableSubInternal;
union upb_MiniTableSub {

@@ -20,4 +25,2 @@ const struct upb_MiniTable* UPB_PRIVATE(submsg);

typedef union upb_MiniTableSub upb_MiniTableSubInternal;
#ifdef __cplusplus

@@ -24,0 +27,0 @@ extern "C" {

@@ -39,16 +39,21 @@ // Protocol Buffers - Google's data interchange format

UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
const upb_MiniTableField* f);
const upb_MiniTable* m, const upb_MiniTableField* f);
// Returns the MiniTable for a message field if it is a submessage and the field
// is linked, otherwise returns NULL.
// Returns the MiniTable for a message field if it is a submessage, otherwise
// returns NULL.
//
// WARNING: if dynamic tree shaking is in use, the return value may be the
// "empty", zero-field placeholder message instead of the real message type.
// If the message is later linked, this function will begin returning the real
// message type.
UPB_API_INLINE const upb_MiniTable* upb_MiniTable_SubMessage(
const upb_MiniTableField* f);
const upb_MiniTable* m, 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);
const upb_MiniTable* m, 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);
const upb_MiniTable* m, const upb_MiniTableField* f);

@@ -65,3 +70,4 @@ // Returns the MiniTableField for the key of a map.

// sub-message.
UPB_API_INLINE bool upb_MiniTable_FieldIsLinked(const upb_MiniTableField* f);
UPB_API_INLINE bool upb_MiniTable_FieldIsLinked(const upb_MiniTable* m,
const upb_MiniTableField* f);

@@ -93,31 +99,4 @@ // If this field is in a oneof, returns the first field in the oneof.

#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
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_MESSAGE_H_ */

@@ -34,6 +34,2 @@ // Protocol Buffers - Google's data interchange format

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)

@@ -47,27 +43,11 @@ #elif defined(UPB_USE_MSC_ATOMICS)

#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(_InterlockedExchange64)
#define upb_Atomic_Store(addr, val, order) \
(void)_InterlockedExchange64((uint64_t volatile *)addr, (uint64_t)val)
#pragma intrinsic(_InterlockedCompareExchange64)
static uintptr_t upb_Atomic_LoadMsc64(uint64_t volatile* addr) {
static uintptr_t upb_Atomic_LoadMsc(uint64_t volatile *addr) {
// Compare exchange with an unlikely value reduces the risk of a spurious

@@ -78,7 +58,31 @@ // (but harmless) store

}
// 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_Load(addr, order) \
_Generic(addr, \
UPB_ATOMIC(uintptr_t) *: upb_Atomic_LoadMsc( \
(uint64_t volatile *)(addr)), \
default: (void *)upb_Atomic_LoadMsc((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), \
default: (void *)_InterlockedExchange64((uint64_t volatile *)addr, \
(uint64_t)val))
#else
// Compare exchange with an unlikely value reduces the risk of a spurious
// (but harmless) store
#define upb_Atomic_Load(addr, order) \
(void *)upb_Atomic_LoadMsc((uint64_t volatile *)(addr))
#define upb_Atomic_Exchange(addr, val, order) \
(void *)_InterlockedExchange64((uint64_t volatile *)addr, (uint64_t)val)
#endif
#pragma intrinsic(_InterlockedCompareExchange64)
static bool upb_Atomic_CompareExchangeMscP64(uint64_t volatile* addr,
uint64_t* expected,
uint64_t desired) {
static bool upb_Atomic_CompareExchangeMscP(uint64_t volatile *addr,
uint64_t *expected,
uint64_t desired) {
uint64_t expect_val = *expected;

@@ -94,177 +98,70 @@ uint64_t actual_val =

#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))
upb_Atomic_CompareExchangeMscP((uint64_t volatile *)addr, \
(uint64_t *)expected, (uint64_t)desired)
#define upb_Atomic_CompareExchangeWeak(addr, expected, desired, success_order, \
failure_order) \
_upb_Atomic_CompareExchangeMscP(addr, expected, (uint64_t)desired, \
sizeof(*addr))
upb_Atomic_CompareExchangeMscP((uint64_t volatile *)addr, \
(uint64_t *)expected, (uint64_t)desired)
#endif
#else // 32 bit pointers
#pragma intrinsic(_InterlockedExchange)
#define upb_Atomic_Store(addr, val, order) \
(void)_InterlockedExchange((uint32_t volatile*)addr, (uint32_t)val)
(void)_InterlockedExchange((uint32_t volatile *)addr, (uint32_t)val)
#pragma intrinsic(_InterlockedCompareExchange)
static uintptr_t upb_Atomic_LoadMsc(uint32_t volatile *addr) {
// Compare exchange with an unlikely value reduces the risk of a spurious
// (but harmless) store
return _InterlockedCompareExchange(addr, 0xDEADC0DE, 0xDEADC0DE);
}
// 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_Load(addr, order) \
_Generic(addr, \
UPB_ATOMIC(uintptr_t) *: upb_Atomic_LoadMsc( \
(uint32_t volatile *)(addr)), \
default: (void *)upb_Atomic_LoadMsc((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))
#define upb_Atomic_Exchange(addr, val, order) \
_Generic(addr, \
UPB_ATOMIC(uintptr_t) *: _InterlockedExchange( \
(uint32_t volatile *)(addr), (uint32_t)val), \
default: (void *)_InterlockedExchange64((uint32_t volatile *)addr, \
(uint32_t)val))
#else
#define upb_Atomic_Load(addr, order) \
(void*)upb_Atomic_LoadMsc32((uint32_t volatile*)(addr))
(void *)upb_Atomic_LoadMsc((uint32_t volatile *)(addr))
#define upb_Atomic_Exchange(addr, val, order) \
(void*)_InterlockedExchange((uint32_t volatile*)addr, (uint32_t)val)
(void *)_InterlockedExchange((uint32_t volatile *)addr, (uint32_t)val)
#endif
#pragma intrinsic(_InterlockedCompareExchange)
static bool upb_Atomic_CompareExchangeMscP(uint32_t volatile *addr,
uint32_t *expected,
uint32_t desired) {
uint32_t expect_val = *expected;
uint32_t actual_val = _InterlockedCompareExchange(addr, desired, expect_val);
if (expect_val != actual_val) {
*expected = actual_val;
return false;
}
return true;
}
#define upb_Atomic_CompareExchangeStrong(addr, expected, desired, \
success_order, failure_order) \
upb_Atomic_CompareExchangeMscP32((uint32_t volatile*)addr, \
(uint32_t*)expected, (uint32_t)desired)
upb_Atomic_CompareExchangeMscP((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)
upb_Atomic_CompareExchangeMscP((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

@@ -313,5 +210,2 @@

#define upb_Atomic_Add(addr, val, order) (*addr += val)
#define upb_Atomic_Sub(addr, val, order) (*addr -= val)
#endif

@@ -318,0 +212,0 @@

@@ -54,20 +54,2 @@ // Protocol Buffers - Google's data interchange format

#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

@@ -111,3 +93,3 @@ #define UPB_HAS_BUILTIN(x) __has_builtin(x)

*/
#define UPB_PTR_AT(msg, ofs, type) ((type*)((char*)(msg) + (ofs)))
#define UPB_PTR_AT(msg, ofs, type) ((type *)((char *)(msg) + (ofs)))

@@ -187,8 +169,2 @@ // A flexible array member may have lower alignment requirements than the struct

#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

@@ -323,11 +299,2 @@ // structs.

#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

@@ -426,8 +393,2 @@ * evaluated. This prevents "unused variable" warnings. */

#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)

@@ -509,2 +470,10 @@ #define UPB_PRESERVE_NONE __attribute__((preserve_none))

/* Disable proto2 arena behavior (TEMPORARY) **********************************/
#ifdef UPB_DISABLE_CLOSED_ENUM_CHECKING
#define UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN 1
#else
#define UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN 0
#endif
#if defined(__cplusplus)

@@ -523,9 +492,13 @@ #if defined(__clang__) || UPB_GNUC_MIN(6, 0)

(!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0)
#define UPB_DESC(sym) proto2_##sym
#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(sym) proto2_##sym
#define UPB_DESC_MINITABLE(sym) proto2__##sym##_msg_init()
#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
#define UPB_DESC(sym) google_protobuf_##sym
#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init()
#else
#define UPB_DESC(sym) google_protobuf_##sym
#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init

@@ -542,8 +515,2 @@ #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

@@ -573,16 +540,10 @@ // array that can be iterated over at runtime.

#define UPB_LINKARR_ATTR
#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
__attribute__((section("linkarr_" #name))) 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]
UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1]
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)

@@ -595,4 +556,3 @@ #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)

#define UPB_LINKARR_APPEND(name) \
__attribute__(( \
section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS
__attribute__((section("__DATA,__la_" #name))) UPB_NO_SANITIZE_ADDRESS
#define UPB_LINKARR_DECLARE(name, type) \

@@ -604,8 +564,7 @@ extern type __start_linkarr_##name __asm( \

"__la_" #name); \
UPB_LINKARR_APPEND(name) \
UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1]
UPB_LINKARR_APPEND(name) 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)
#elif defined(_MSC_VER) && defined(__clang__)

@@ -616,22 +575,11 @@ /* See:

* 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
// Usage of __attribute__ here probably means this is Clang-specific, and would
// not work on MSVC.
#define UPB_LINKARR_APPEND(name) \
__declspec(allocate("la_" #name "$j")) UPB_NO_SANITIZE_ADDRESS
#define UPB_LINKARR_DECLARE(name, type) \
__declspec(allocate("la_" #name "$a")) type __start_linkarr_##name; \
__declspec(allocate("la_" #name "$z")) type __stop_linkarr_##name; \
UPB_LINKARR_APPEND(name) type UPB_linkarr_internal_empty_##name[1] = {0}
#define UPB_LINKARR_START(name) (&__start_linkarr_##name)

@@ -642,113 +590,8 @@ #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name)

// Linker arrays are not supported on this platform. Make macros no-ops.
// Linker arrays are not supported on this platform. Make appends a no-op but
// don't define the other macros.
#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$XCU", long, read)
#define UPB_CONSTRUCTOR(name, unique_name) \
static void __cdecl UPB_PRIVATE(name)(void); \
__declspec(allocate(".CRT$XCU"), 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.

@@ -755,0 +598,0 @@ // This macro can be set to enable these API changes ahead of time, so that

@@ -23,6 +23,2 @@ // Protocol Buffers - Google's data interchange format

#if UPB_MSAN
#include <sanitizer/msan_interface.h>
#endif
#ifdef __cplusplus

@@ -75,13 +71,2 @@ extern "C" {

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

@@ -88,0 +73,0 @@ // it is unpoisoned.

@@ -48,3 +48,2 @@ // Protocol Buffers - Google's data interchange format

#undef UPB_MUSTTAIL
#undef UPB_PRESERVE_MOST
#undef UPB_PRESERVE_NONE

@@ -60,8 +59,9 @@ #undef UPB_FASTTABLE_SUPPORTED

#undef UPB_HWASAN_POISON_TAG
#undef UPB_MSAN
#undef UPB_MALLOC_ALIGN
#undef UPB_TSAN
#undef UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN
#undef UPB_DEPRECATED
#undef UPB_GNUC_MIN
#undef UPB_DESCRIPTOR_UPB_H_FILENAME
#undef UPB_DESC
#undef UPB_DESC_MINITABLE

@@ -80,3 +80,2 @@ #undef UPB_IS_GOOGLE3

#undef UPB_HAS_ATTRIBUTE
#undef UPB_HAS_CPP_ATTRIBUTE
#undef UPB_HAS_BUILTIN

@@ -91,4 +90,1 @@ #undef UPB_HAS_EXTENSION

#undef UPB_ARM64_BTI_DEFAULT
#undef UPB_DEPRECATE_AND_INLINE
#undef UPB_MAYBE_ASSUME
#undef UPB_ATTR_CONST

@@ -17,2 +17,8 @@ // Protocol Buffers - Google's data interchange format

typedef enum {
kUpb_Syntax_Proto2 = 2,
kUpb_Syntax_Proto3 = 3,
kUpb_Syntax_Editions = 99
} upb_Syntax;
// Forward declarations for circular references.

@@ -19,0 +25,0 @@ typedef struct upb_DefPool upb_DefPool;

@@ -10,11 +10,3 @@ // Protocol Buffers - Google's data interchange format

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "upb/base/status.h"
#include "upb/base/string_view.h"
#include "upb/hash/common.h"
#include "upb/hash/int_table.h"

@@ -24,8 +16,2 @@ #include "upb/hash/str_table.h"

#include "upb/mem/arena.h"
#include "upb/mini_descriptor/decode.h"
#include "upb/mini_table/extension.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/file.h"
#include "upb/mini_table/generated_registry.h"
#include "upb/mini_table/message.h"
#include "upb/reflection/def.h"

@@ -35,4 +21,8 @@ #include "upb/reflection/def_type.h"

#include "upb/reflection/internal/def_builder.h"
#include "upb/reflection/internal/enum_def.h"
#include "upb/reflection/internal/enum_value_def.h"
#include "upb/reflection/internal/field_def.h"
#include "upb/reflection/internal/file_def.h"
#include "upb/reflection/internal/message_def.h"
#include "upb/reflection/internal/service_def.h"
#include "upb/reflection/internal/upb_edition_defaults.h"

@@ -42,3 +32,2 @@

#include "upb/port/def.inc"
#include "upb/wire/decode.h"

@@ -51,4 +40,3 @@ struct upb_DefPool {

upb_ExtensionRegistry* extreg;
const upb_GeneratedRegistryRef* generated_extreg;
const google_protobuf_FeatureSetDefaults* feature_set_defaults;
const UPB_DESC(FeatureSetDefaults) * feature_set_defaults;
upb_MiniTablePlatform platform;

@@ -58,7 +46,5 @@ void* scratch_data;

size_t bytes_loaded;
bool disable_closed_enum_checking;
};
void upb_DefPool_Free(upb_DefPool* s) {
upb_GeneratedRegistry_Release(s->generated_extreg);
upb_Arena_Free(s->arena);

@@ -77,3 +63,2 @@ upb_gfree(s->scratch_data);

s->bytes_loaded = 0;
s->disable_closed_enum_checking = false;

@@ -91,5 +76,2 @@ s->scratch_size = 240;

s->generated_extreg = upb_GeneratedRegistry_Load();
if (!s->generated_extreg) goto err;
s->platform = kUpb_MiniTablePlatform_Native;

@@ -112,13 +94,4 @@

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;
}
const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults(
const upb_DefPool* s) {
const UPB_DESC(FeatureSetDefaults) *
upb_DefPool_FeatureSetDefaults(const upb_DefPool* s) {
return s->feature_set_defaults;

@@ -131,4 +104,4 @@ }

upb_Status* status) {
const google_protobuf_FeatureSetDefaults* defaults = google_protobuf_FeatureSetDefaults_parse(
serialized_defaults, serialized_len, s->arena);
const UPB_DESC(FeatureSetDefaults)* defaults = UPB_DESC(
FeatureSetDefaults_parse)(serialized_defaults, serialized_len, s->arena);
if (!defaults) {

@@ -144,4 +117,4 @@ upb_Status_SetErrorFormat(status, "Failed to parse defaults");

}
int min_edition = google_protobuf_FeatureSetDefaults_minimum_edition(defaults);
int max_edition = google_protobuf_FeatureSetDefaults_maximum_edition(defaults);
int min_edition = UPB_DESC(FeatureSetDefaults_minimum_edition(defaults));
int max_edition = UPB_DESC(FeatureSetDefaults_maximum_edition(defaults));
if (min_edition > max_edition) {

@@ -154,9 +127,10 @@ upb_Status_SetErrorFormat(status, "Invalid edition range %s to %s",

size_t size;
const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const*
default_list = google_protobuf_FeatureSetDefaults_defaults(defaults, &size);
int prev_edition = google_protobuf_EDITION_UNKNOWN;
const UPB_DESC(
FeatureSetDefaults_FeatureSetEditionDefault)* const* default_list =
UPB_DESC(FeatureSetDefaults_defaults(defaults, &size));
int prev_edition = UPB_DESC(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) {
int edition = UPB_DESC(
FeatureSetDefaults_FeatureSetEditionDefault_edition(default_list[i]));
if (edition == UPB_DESC(EDITION_UNKNOWN)) {
upb_Status_SetErrorFormat(status, "Invalid edition UNKNOWN specified");

@@ -392,3 +366,3 @@ return false;

upb_DefBuilder* const builder, upb_DefPool* const s,
const google_protobuf_FileDescriptorProto* const file_proto,
const UPB_DESC(FileDescriptorProto) * const file_proto,
const upb_StringView name, upb_Status* const status) {

@@ -405,3 +379,3 @@ if (UPB_SETJMP(builder->err) != 0) {

!(builder->legacy_features =
google_protobuf_FeatureSet_new(builder->tmp_arena))) {
UPB_DESC(FeatureSet_new)(builder->tmp_arena))) {
_upb_DefBuilder_OomErr(builder);

@@ -422,5 +396,5 @@ } else {

static const upb_FileDef* _upb_DefPool_AddFile(
upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
upb_DefPool* s, const UPB_DESC(FileDescriptorProto) * file_proto,
const upb_MiniTableFile* layout, upb_Status* status) {
const upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto);
const upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto);

@@ -456,5 +430,6 @@ // Determine whether we already know about this file.

const upb_FileDef* upb_DefPool_AddFile(
upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
upb_Status* status) {
const upb_FileDef* upb_DefPool_AddFile(upb_DefPool* s,
const UPB_DESC(FileDescriptorProto) *
file_proto,
upb_Status* status) {
return _upb_DefPool_AddFile(s, file_proto, NULL, status);

@@ -468,3 +443,3 @@ }

_upb_DefPool_Init** deps = init->deps;
google_protobuf_FileDescriptorProto* file;
UPB_DESC(FileDescriptorProto) * file;
upb_Arena* arena;

@@ -485,3 +460,3 @@ upb_Status status;

file = google_protobuf_FileDescriptorProto_parse_ex(
file = UPB_DESC(FileDescriptorProto_parse_ex)(
init->descriptor.data, init->descriptor.size, NULL,

@@ -573,6 +548,1 @@ kUpb_DecodeOption_AliasString, arena);

}
const upb_ExtensionRegistry* _upb_DefPool_GeneratedExtensionRegistry(
const upb_DefPool* s) {
return upb_GeneratedRegistry_Get(s->generated_extreg);
}

@@ -29,4 +29,4 @@ // Protocol Buffers - Google's data interchange format

UPB_API const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults(
const upb_DefPool* s);
UPB_API const UPB_DESC(FeatureSetDefaults) *
upb_DefPool_FeatureSetDefaults(const upb_DefPool* s);

@@ -60,4 +60,4 @@ UPB_API bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s,

UPB_API const upb_FieldDef* upb_DefPool_FindExtensionByName(
const upb_DefPool* s, const char* sym);
UPB_API const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s,
const char* sym);

@@ -72,3 +72,3 @@ const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize(

UPB_API const upb_ServiceDef* upb_DefPool_FindServiceByName(
const upb_DefPool* s, const char* name);
const upb_DefPool* s, const char* name);

@@ -82,3 +82,3 @@ const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize(

UPB_API const upb_FileDef* upb_DefPool_AddFile(
upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
upb_DefPool* s, const UPB_DESC(FileDescriptorProto) * file_proto,
upb_Status* status);

@@ -93,16 +93,2 @@

// 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);
#ifdef __cplusplus

@@ -109,0 +95,0 @@ } /* extern "C" */

@@ -26,3 +26,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"

@@ -39,4 +38,4 @@ #include "upb/reflection/internal/desc_state.h"

struct upb_EnumDef {
UPB_ALIGN_AS(8) const google_protobuf_EnumOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
UPB_ALIGN_AS(8) const UPB_DESC(EnumOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const upb_MiniTableEnum* layout; // Only for proto2.

@@ -55,3 +54,3 @@ const upb_FileDef* file;

int32_t defaultval;
google_protobuf_SymbolVisibility visibility;
UPB_DESC(SymbolVisibility) visibility;
bool is_sorted; // Whether all of the values are defined in ascending order.

@@ -82,3 +81,3 @@ };

const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
const UPB_DESC(EnumOptions) * upb_EnumDef_Options(const upb_EnumDef* e) {
return e->opts;

@@ -91,7 +90,8 @@ }

const google_protobuf_FeatureSet* upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e) {
const UPB_DESC(FeatureSet) *
upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e) {
return e->resolved_features;
}
google_protobuf_SymbolVisibility upb_EnumDef_Visibility(const upb_EnumDef* e) {
UPB_DESC(SymbolVisibility) upb_EnumDef_Visibility(const upb_EnumDef* e) {
return e->visibility;

@@ -169,12 +169,12 @@ }

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;
if (UPB_TREAT_CLOSED_ENUMS_LIKE_OPEN) return false;
return upb_EnumDef_IsSpecifiedAsClosed(e);
}
bool upb_EnumDef_IsSpecifiedAsClosed(const upb_EnumDef* e) {
return UPB_DESC(FeatureSet_enum_type)(e->resolved_features) ==
UPB_DESC(FeatureSet_CLOSED);
}
bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a,

@@ -246,7 +246,7 @@ upb_StringView* out) {

static void create_enumdef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_EnumDescriptorProto* enum_proto,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(EnumDescriptorProto) * enum_proto,
const UPB_DESC(FeatureSet*) parent_features,
upb_EnumDef* e) {
const google_protobuf_EnumValueDescriptorProto* const* values;
const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* res_ranges;
const UPB_DESC(EnumValueDescriptorProto)* const* values;
const UPB_DESC(EnumDescriptorProto_EnumReservedRange)* const* res_ranges;
const upb_StringView* res_names;

@@ -258,3 +258,3 @@ upb_StringView name;

e->resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_EnumOptions_features(e->opts));
ctx, parent_features, UPB_DESC(EnumOptions_features)(e->opts));

@@ -264,3 +264,3 @@ // Must happen before _upb_DefBuilder_Add()

name = google_protobuf_EnumDescriptorProto_name(enum_proto);
name = UPB_DESC(EnumDescriptorProto_name)(enum_proto);

@@ -271,24 +271,4 @@ e->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);

values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n_value);
values = UPB_DESC(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);

@@ -300,2 +280,3 @@ if (!ok) _upb_DefBuilder_OomErr(ctx);

e->defaultval = 0;
e->value_count = n_value;

@@ -305,12 +286,18 @@ e->values = _upb_EnumValueDefs_New(ctx, prefix, n_value, values,

if (n_value == 0) {
_upb_DefBuilder_Errf(ctx, "enums must contain at least one value (%s)",
e->full_name);
}
res_ranges =
google_protobuf_EnumDescriptorProto_reserved_range(enum_proto, &n_res_range);
UPB_DESC(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);
res_names =
UPB_DESC(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);
e->visibility = UPB_DESC(EnumDescriptorProto_visibility)(enum_proto);

@@ -331,4 +318,5 @@ if (!upb_inttable_compact(&e->iton, ctx->arena)) _upb_DefBuilder_OomErr(ctx);

upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n,
const google_protobuf_EnumDescriptorProto* const* protos,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(EnumDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
const upb_MessageDef* containing_type) {

@@ -335,0 +323,0 @@ _upb_DefType_CheckPadding(sizeof(upb_EnumDef));

@@ -13,9 +13,4 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include <stdint.h>
#include "upb/base/string_view.h"
#include "upb/mem/arena.h"
#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -42,2 +37,3 @@ // Must be last.

bool upb_EnumDef_IsClosed(const upb_EnumDef* e);
bool upb_EnumDef_IsSpecifiedAsClosed(const upb_EnumDef* e);

@@ -49,5 +45,5 @@ // Creates a mini descriptor string for an enum, returns true on success.

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);
const UPB_DESC(EnumOptions) * upb_EnumDef_Options(const upb_EnumDef* e);
const UPB_DESC(FeatureSet) * upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e);
UPB_DESC(SymbolVisibility) upb_EnumDef_Visibility(const upb_EnumDef* e);

@@ -54,0 +50,0 @@ upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i);

@@ -10,6 +10,2 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/enum_def.h"

@@ -41,3 +37,3 @@ #include "upb/reflection/field_def.h"

upb_DefBuilder* ctx, int n,
const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos,
const UPB_DESC(EnumDescriptorProto_EnumReservedRange) * const* protos,
const upb_EnumDef* e) {

@@ -49,5 +45,5 @@ upb_EnumReservedRange* r =

const int32_t start =
google_protobuf_EnumDescriptorProto_EnumReservedRange_start(protos[i]);
UPB_DESC(EnumDescriptorProto_EnumReservedRange_start)(protos[i]);
const int32_t end =
google_protobuf_EnumDescriptorProto_EnumReservedRange_end(protos[i]);
UPB_DESC(EnumDescriptorProto_EnumReservedRange_end)(protos[i]);

@@ -54,0 +50,0 @@ // A full validation would also check that each range is disjoint, and that

@@ -18,3 +18,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/enum_def.h"

@@ -29,4 +28,4 @@ #include "upb/reflection/enum_value_def.h"

struct upb_EnumValueDef {
UPB_ALIGN_AS(8) const google_protobuf_EnumValueOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
UPB_ALIGN_AS(8) const UPB_DESC(EnumValueOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const upb_EnumDef* parent;

@@ -63,4 +62,4 @@ const char* full_name;

const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options(
const upb_EnumValueDef* v) {
const UPB_DESC(EnumValueOptions) *
upb_EnumValueDef_Options(const upb_EnumValueDef* v) {
return v->opts;

@@ -73,4 +72,4 @@ }

const google_protobuf_FeatureSet* upb_EnumValueDef_ResolvedFeatures(
const upb_EnumValueDef* e) {
const UPB_DESC(FeatureSet) *
upb_EnumValueDef_ResolvedFeatures(const upb_EnumValueDef* e) {
return e->resolved_features;

@@ -99,4 +98,5 @@ }

static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_EnumValueDescriptorProto* val_proto,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(EnumValueDescriptorProto*)
val_proto,
const UPB_DESC(FeatureSet*) parent_features,
upb_EnumDef* e, upb_EnumValueDef* v) {

@@ -106,9 +106,9 @@ UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions,

v->resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_EnumValueOptions_features(v->opts));
ctx, parent_features, UPB_DESC(EnumValueOptions_features)(v->opts));
upb_StringView name = google_protobuf_EnumValueDescriptorProto_name(val_proto);
upb_StringView name = UPB_DESC(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);
v->number = UPB_DESC(EnumValueDescriptorProto_number)(val_proto);
_upb_DefBuilder_Add(ctx, v->full_name,

@@ -121,7 +121,20 @@ _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL));

static void _upb_EnumValueDef_CheckZeroValue(upb_DefBuilder* ctx,
const upb_EnumDef* e,
const upb_EnumValueDef* v, int n) {
// 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.
if (upb_EnumDef_IsSpecifiedAsClosed(e) || n == 0 || v[0].number == 0) return;
_upb_DefBuilder_Errf(ctx, "for open enums, the first value must be zero (%s)",
upb_EnumDef_FullName(e));
}
// 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_DESC(EnumValueDescriptorProto*) const* protos,
const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e,
bool* is_sorted) {
_upb_DefType_CheckPadding(sizeof(upb_EnumValueDef));

@@ -141,3 +154,5 @@

_upb_EnumValueDef_CheckZeroValue(ctx, e, v, n);
return v;
}

@@ -14,3 +14,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -30,6 +29,6 @@ // Must be last.

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);
const UPB_DESC(EnumValueOptions) *
upb_EnumValueDef_Options(const upb_EnumValueDef* v);
const UPB_DESC(FeatureSet) *
upb_EnumValueDef_ResolvedFeatures(const upb_EnumValueDef* e);

@@ -36,0 +35,0 @@ #ifdef __cplusplus

@@ -12,4 +12,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/extension_range.h"

@@ -24,4 +22,4 @@ #include "upb/reflection/field_def.h"

struct upb_ExtensionRange {
const google_protobuf_ExtensionRangeOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
const UPB_DESC(ExtensionRangeOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
int32_t start;

@@ -35,4 +33,4 @@ int32_t end;

const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options(
const upb_ExtensionRange* r) {
const UPB_DESC(ExtensionRangeOptions) *
upb_ExtensionRange_Options(const upb_ExtensionRange* r) {
return r->opts;

@@ -53,4 +51,4 @@ }

upb_DefBuilder* ctx, int n,
const google_protobuf_DescriptorProto_ExtensionRange* const* protos,
const google_protobuf_FeatureSet* parent_features, const upb_MessageDef* m) {
const UPB_DESC(DescriptorProto_ExtensionRange*) const* protos,
const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* m) {
upb_ExtensionRange* r = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_ExtensionRange, n);

@@ -62,11 +60,12 @@

r[i].resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_ExtensionRangeOptions_features(r[i].opts));
ctx, parent_features,
UPB_DESC(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;
UPB_DESC(DescriptorProto_ExtensionRange_start)(protos[i]);
const int32_t end = UPB_DESC(DescriptorProto_ExtensionRange_end)(protos[i]);
const int32_t max = UPB_DESC(MessageOptions_message_set_wire_format)(
upb_MessageDef_Options(m))
? INT32_MAX
: kUpb_MaxFieldNumber + 1;

@@ -73,0 +72,0 @@ // A full validation would also check that each range is disjoint, and that

@@ -13,6 +13,3 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -30,6 +27,6 @@ // Must be last.

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);
const UPB_DESC(ExtensionRangeOptions) *
upb_ExtensionRange_Options(const upb_ExtensionRange* r);
const UPB_DESC(FeatureSet) *
upb_ExtensionRange_ResolvedFeatures(const upb_ExtensionRange* e);

@@ -36,0 +33,0 @@ #ifdef __cplusplus

@@ -32,3 +32,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"

@@ -54,4 +53,4 @@ #include "upb/reflection/internal/def_pool.h"

struct upb_FieldDef {
UPB_ALIGN_AS(8) const google_protobuf_FieldOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
UPB_ALIGN_AS(8) const UPB_DESC(FieldOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const upb_FileDef* file;

@@ -77,3 +76,3 @@ const upb_MessageDef* msgdef;

const upb_EnumDef* enumdef;
const google_protobuf_FieldDescriptorProto* unresolved;
const UPB_DESC(FieldDescriptorProto) * unresolved;
} sub;

@@ -96,3 +95,3 @@ uint32_t number_;

const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f) {
const UPB_DESC(FieldOptions) * upb_FieldDef_Options(const upb_FieldDef* f) {
return f->opts;

@@ -105,3 +104,4 @@ }

const google_protobuf_FeatureSet* upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f) {
const UPB_DESC(FeatureSet) *
upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f) {
return f->resolved_features;

@@ -138,4 +138,4 @@ }

return _upb_FieldDef_IsPackable(f) &&
google_protobuf_FeatureSet_repeated_field_encoding(f->resolved_features) ==
google_protobuf_FeatureSet_PACKED;
UPB_DESC(FeatureSet_repeated_field_encoding(f->resolved_features)) ==
UPB_DESC(FeatureSet_PACKED);
}

@@ -255,4 +255,4 @@

if (upb_FieldDef_Type(f) != kUpb_FieldType_String) return false;
return google_protobuf_FeatureSet_utf8_validation(f->resolved_features) ==
google_protobuf_FeatureSet_VERIFY;
return UPB_DESC(FeatureSet_utf8_validation(f->resolved_features)) ==
UPB_DESC(FeatureSet_VERIFY);
}

@@ -344,4 +344,4 @@

bool upb_FieldDef_IsRequired(const upb_FieldDef* f) {
return google_protobuf_FeatureSet_field_presence(f->resolved_features) ==
google_protobuf_FeatureSet_LEGACY_REQUIRED;
return UPB_DESC(FeatureSet_field_presence)(f->resolved_features) ==
UPB_DESC(FeatureSet_LEGACY_REQUIRED);
}

@@ -539,4 +539,3 @@

static void set_default_default(upb_DefBuilder* ctx, upb_FieldDef* f,
bool must_be_empty) {
static void set_default_default(upb_DefBuilder* ctx, upb_FieldDef* f) {
switch (upb_FieldDef_CType(f)) {

@@ -563,10 +562,4 @@ case kUpb_CType_Int32:

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));
}
const upb_EnumValueDef* v = upb_EnumDef_Value(f->sub.enumdef, 0);
f->defaultval.sint = upb_EnumValueDef_Number(v);
break;

@@ -581,27 +574,28 @@ }

upb_DefBuilder* ctx, upb_FieldDef* f,
const google_protobuf_FieldDescriptorProto* proto,
const google_protobuf_FieldOptions* options, google_protobuf_Edition edition,
google_protobuf_FeatureSet* features) {
const UPB_DESC(FieldDescriptorProto*) proto,
const UPB_DESC(FieldOptions*) options, upb_Syntax syntax,
UPB_DESC(FeatureSet*) features) {
bool ret = false;
if (google_protobuf_FieldDescriptorProto_label(proto) == kUpb_Label_Required) {
if (edition == google_protobuf_EDITION_PROTO3) {
if (UPB_DESC(FieldDescriptorProto_label)(proto) == kUpb_Label_Required) {
if (syntax == kUpb_Syntax_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);
int val = UPB_DESC(FeatureSet_LEGACY_REQUIRED);
UPB_DESC(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);
if (UPB_DESC(FieldDescriptorProto_type)(proto) == kUpb_FieldType_Group) {
int val = UPB_DESC(FeatureSet_DELIMITED);
UPB_DESC(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);
if (UPB_DESC(FieldOptions_has_packed)(options)) {
int val = UPB_DESC(FieldOptions_packed)(options)
? UPB_DESC(FeatureSet_PACKED)
: UPB_DESC(FeatureSet_EXPANDED);
UPB_DESC(FeatureSet_set_repeated_field_encoding(features, val));
ret = true;

@@ -614,4 +608,5 @@ }

static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_FeatureSet* parent_features,
const google_protobuf_FieldDescriptorProto* field_proto,
const UPB_DESC(FeatureSet*) parent_features,
const UPB_DESC(FieldDescriptorProto*)
field_proto,
upb_MessageDef* m, upb_FieldDef* f) {

@@ -621,7 +616,7 @@ // Must happen before _upb_DefBuilder_Add()

const upb_StringView name = google_protobuf_FieldDescriptorProto_name(field_proto);
const upb_StringView name = UPB_DESC(FieldDescriptorProto_name)(field_proto);
f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
f->number_ = google_protobuf_FieldDescriptorProto_number(field_proto);
f->number_ = UPB_DESC(FieldDescriptorProto_number)(field_proto);
f->is_proto3_optional =
google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
UPB_DESC(FieldDescriptorProto_proto3_optional)(field_proto);
f->msgdef = m;

@@ -632,11 +627,11 @@ f->scope.oneof = NULL;

google_protobuf_Edition edition = upb_FileDef_Edition(f->file);
const google_protobuf_FeatureSet* unresolved_features =
google_protobuf_FieldOptions_features(f->opts);
upb_Syntax syntax = upb_FileDef_Syntax(f->file);
const UPB_DESC(FeatureSet*) unresolved_features =
UPB_DESC(FieldOptions_features)(f->opts);
bool implicit = false;
if (_upb_DefBuilder_IsLegacyEdition(edition)) {
if (syntax != kUpb_Syntax_Editions) {
upb_Message_Clear(UPB_UPCAST(ctx->legacy_features),
UPB_DESC_MINITABLE(FeatureSet));
if (_upb_FieldDef_InferLegacyFeatures(ctx, f, field_proto, f->opts, edition,
if (_upb_FieldDef_InferLegacyFeatures(ctx, f, field_proto, f->opts, syntax,
ctx->legacy_features)) {

@@ -648,4 +643,4 @@ implicit = true;

if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
int oneof_index = google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) {
int oneof_index = UPB_DESC(FieldDescriptorProto_oneof_index)(field_proto);

@@ -671,18 +666,18 @@ if (!m) {

f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
f->label_ = (int)UPB_DESC(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) {
UPB_DESC(FeatureSet_field_presence)(f->resolved_features) ==
UPB_DESC(FeatureSet_LEGACY_REQUIRED)) {
f->label_ = kUpb_Label_Required;
}
if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
if (!UPB_DESC(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);
f->has_json_name = UPB_DESC(FieldDescriptorProto_has_json_name)(field_proto);
if (f->has_json_name) {
const upb_StringView sv =
google_protobuf_FieldDescriptorProto_json_name(field_proto);
UPB_DESC(FieldDescriptorProto_json_name)(field_proto);
f->json_name = upb_strdup2(sv.data, sv.size, ctx->arena);

@@ -694,7 +689,7 @@ } else {

const bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto);
const bool has_type = UPB_DESC(FieldDescriptorProto_has_type)(field_proto);
const bool has_type_name =
google_protobuf_FieldDescriptorProto_has_type_name(field_proto);
UPB_DESC(FieldDescriptorProto_has_type_name)(field_proto);
f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
f->type_ = (int)UPB_DESC(FieldDescriptorProto_type)(field_proto);

@@ -740,3 +735,3 @@ if (has_type) {

if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) {
if (upb_FieldDef_Label(f) != kUpb_Label_Optional) {

@@ -753,15 +748,15 @@ _upb_DefBuilder_Errf(ctx, "fields in oneof must have OPTIONAL label (%s)",

f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) ||
google_protobuf_FeatureSet_field_presence(f->resolved_features) !=
google_protobuf_FeatureSet_IMPLICIT));
UPB_DESC(FeatureSet_field_presence)(f->resolved_features) !=
UPB_DESC(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) {
static void _upb_FieldDef_CreateExt(upb_DefBuilder* ctx, const char* prefix,
const UPB_DESC(FeatureSet*) parent_features,
const UPB_DESC(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)) {
if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) {
_upb_DefBuilder_Errf(ctx, "oneof_index provided for extension field (%s)",

@@ -781,11 +776,12 @@ f->full_name);

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) {
static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix,
const UPB_DESC(FeatureSet*)
parent_features,
const UPB_DESC(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 (!UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) {
if (f->is_proto3_optional) {

@@ -802,7 +798,7 @@ _upb_DefBuilder_Errf(

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_FieldDef* _upb_Extensions_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(FieldDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
const char* prefix, upb_MessageDef* m) {
_upb_DefType_CheckPadding(sizeof(upb_FieldDef));

@@ -821,7 +817,8 @@ upb_FieldDef* defs = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_FieldDef, n);

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_FieldDef* _upb_FieldDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(FieldDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
const char* prefix, upb_MessageDef* m,
bool* is_sorted) {
_upb_DefType_CheckPadding(sizeof(upb_FieldDef));

@@ -854,5 +851,5 @@ upb_FieldDef* defs = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_FieldDef, n);

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);
const UPB_DESC(FieldDescriptorProto)* field_proto = f->sub.unresolved;
upb_StringView name = UPB_DESC(FieldDescriptorProto_type_name)(field_proto);
bool has_name = UPB_DESC(FieldDescriptorProto_has_type_name)(field_proto);
switch ((int)f->type_) {

@@ -875,4 +872,4 @@ case UPB_FIELD_TYPE_UNSPECIFIED: {

// kUpb_FieldType_Group.
if (google_protobuf_FeatureSet_message_encoding(f->resolved_features) ==
google_protobuf_FeatureSet_DELIMITED &&
if (UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) ==
UPB_DESC(FeatureSet_DELIMITED) &&
!upb_MessageDef_IsMapEntry(def) &&

@@ -955,4 +952,5 @@ !(f->msgdef && upb_MessageDef_IsMapEntry(f->msgdef))) {

upb_FieldDef* f,
const google_protobuf_FieldDescriptorProto* field_proto) {
if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
const UPB_DESC(FieldDescriptorProto) *
field_proto) {
if (!UPB_DESC(FieldDescriptorProto_has_extendee)(field_proto)) {
_upb_DefBuilder_Errf(ctx, "extension for field '%s' had no extendee",

@@ -962,3 +960,3 @@ f->full_name);

upb_StringView name = google_protobuf_FieldDescriptorProto_extendee(field_proto);
upb_StringView name = UPB_DESC(FieldDescriptorProto_extendee)(field_proto);
const upb_MessageDef* m =

@@ -1008,28 +1006,12 @@ _upb_DefBuilder_Resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG);

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);
const UPB_DESC(FieldDescriptorProto) *
field_proto) {
// 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)) {
if (UPB_DESC(FieldDescriptorProto_has_default_value)(field_proto)) {
upb_StringView defaultval =
google_protobuf_FieldDescriptorProto_default_value(field_proto);
UPB_DESC(FieldDescriptorProto_default_value)(field_proto);
if (must_be_empty) {
if (upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3) {
_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)",

@@ -1048,3 +1030,3 @@ f->full_name);

} else {
set_default_default(ctx, f, must_be_empty);
set_default_default(ctx, f);
f->has_default = false;

@@ -1057,3 +1039,3 @@ }

// We have to stash this away since resolve_subdef() may overwrite it.
const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved;
const UPB_DESC(FieldDescriptorProto)* field_proto = f->sub.unresolved;

@@ -1060,0 +1042,0 @@ resolve_subdef(ctx, prefix, f);

@@ -21,3 +21,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -77,4 +76,5 @@ // Must be last.

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);
const UPB_DESC(FieldOptions) * upb_FieldDef_Options(const upb_FieldDef* f);
const UPB_DESC(FeatureSet) *
upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f);
UPB_API const upb_OneofDef* upb_FieldDef_RealContainingOneof(

@@ -81,0 +81,0 @@ const upb_FieldDef* f);

@@ -19,3 +19,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"

@@ -33,7 +32,7 @@ #include "upb/reflection/internal/def_pool.h"

struct upb_FileDef {
const google_protobuf_FileOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
const UPB_DESC(FileOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const char* name;
const char* package;
google_protobuf_Edition edition;
UPB_DESC(Edition) edition;

@@ -58,2 +57,3 @@ const upb_FileDef** deps;

int ext_count; // All exts in the file.
upb_Syntax syntax;
};

@@ -64,7 +64,7 @@

switch (edition) {
case google_protobuf_EDITION_PROTO2:
case UPB_DESC(EDITION_PROTO2):
return "PROTO2";
case google_protobuf_EDITION_PROTO3:
case UPB_DESC(EDITION_PROTO3):
return "PROTO3";
case google_protobuf_EDITION_2023:
case UPB_DESC(EDITION_2023):
return "2023";

@@ -76,7 +76,8 @@ default:

const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) {
const UPB_DESC(FileOptions) * upb_FileDef_Options(const upb_FileDef* f) {
return f->opts;
}
const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f) {
const UPB_DESC(FeatureSet) *
upb_FileDef_ResolvedFeatures(const upb_FileDef* f) {
return f->resolved_features;

@@ -95,6 +96,10 @@ }

google_protobuf_Edition upb_FileDef_Edition(const upb_FileDef* f) { return f->edition; }
UPB_DESC(Edition) upb_FileDef_Edition(const upb_FileDef* f) {
return f->edition;
}
const char* _upb_FileDef_RawPackage(const upb_FileDef* f) { return f->package; }
upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f) { return f->syntax; }
int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) {

@@ -122,6 +127,2 @@ return f->top_lvl_msg_count;

bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f) {
return upb_DefPool_ClosedEnumCheckingDisabled(f->symtab);
}
int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) {

@@ -200,9 +201,9 @@ return f->top_lvl_enum_count;

static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) {
static int count_exts_in_msg(const UPB_DESC(DescriptorProto) * msg_proto) {
size_t n;
google_protobuf_DescriptorProto_extension(msg_proto, &n);
UPB_DESC(DescriptorProto_extension)(msg_proto, &n);
int ext_count = n;
const google_protobuf_DescriptorProto* const* nested_msgs =
google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
const UPB_DESC(DescriptorProto)* const* nested_msgs =
UPB_DESC(DescriptorProto_nested_type)(msg_proto, &n);
for (size_t i = 0; i < n; i++) {

@@ -215,9 +216,9 @@ ext_count += count_exts_in_msg(nested_msgs[i]);

const google_protobuf_FeatureSet* _upb_FileDef_FindEdition(upb_DefBuilder* ctx,
int edition) {
const google_protobuf_FeatureSetDefaults* defaults =
const UPB_DESC(FeatureSet*)
_upb_FileDef_FindEdition(upb_DefBuilder* ctx, int edition) {
const UPB_DESC(FeatureSetDefaults)* defaults =
upb_DefPool_FeatureSetDefaults(ctx->symtab);
int min = google_protobuf_FeatureSetDefaults_minimum_edition(defaults);
int max = google_protobuf_FeatureSetDefaults_maximum_edition(defaults);
int min = UPB_DESC(FeatureSetDefaults_minimum_edition)(defaults);
int max = UPB_DESC(FeatureSetDefaults_maximum_edition)(defaults);
if (edition < min) {

@@ -231,3 +232,3 @@ _upb_DefBuilder_Errf(ctx,

}
if (edition > max && edition != google_protobuf_EDITION_UNSTABLE) {
if (edition > max && edition != UPB_DESC(EDITION_UNSTABLE)) {
_upb_DefBuilder_Errf(ctx,

@@ -242,7 +243,7 @@ "Edition %s is later than the maximum edition %s "

size_t n;
const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* const* d =
google_protobuf_FeatureSetDefaults_defaults(defaults, &n);
const google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* result = NULL;
const UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault)* const* d =
UPB_DESC(FeatureSetDefaults_defaults)(defaults, &n);
const UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault)* result = NULL;
for (size_t i = 0; i < n; i++) {
if (google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_edition(d[i]) >
if (UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault_edition)(d[i]) >
edition) {

@@ -261,7 +262,6 @@ break;

// 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);
const UPB_DESC(FeatureSet)* fixed = UPB_DESC(
FeatureSetDefaults_FeatureSetEditionDefault_fixed_features)(result);
const UPB_DESC(FeatureSet)* overridable = UPB_DESC(
FeatureSetDefaults_FeatureSetEditionDefault_overridable_features)(result);
if (!fixed && !overridable) {

@@ -280,10 +280,10 @@ _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s",

void _upb_FileDef_Create(upb_DefBuilder* ctx,
const google_protobuf_FileDescriptorProto* file_proto) {
const UPB_DESC(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_DESC(DescriptorProto)* const* msgs;
const UPB_DESC(EnumDescriptorProto)* const* enums;
const UPB_DESC(FieldDescriptorProto)* const* exts;
const UPB_DESC(ServiceDescriptorProto)* const* services;
const upb_StringView* strs;

@@ -297,5 +297,5 @@ const int32_t* public_deps;

// Count all extensions in the file, to build a flat array of layouts.
google_protobuf_FileDescriptorProto_extension(file_proto, &n);
UPB_DESC(FileDescriptorProto_extension)(file_proto, &n);
int ext_count = n;
msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
msgs = UPB_DESC(FileDescriptorProto_message_type)(file_proto, &n);
for (size_t i = 0; i < n; i++) {

@@ -326,3 +326,3 @@ ext_count += count_exts_in_msg(msgs[i]);

upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto);
upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto);
file->name = _strviewdup(ctx, name);

@@ -333,3 +333,3 @@ if (strlen(file->name) != name.size) {

upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto);
upb_StringView package = UPB_DESC(FileDescriptorProto_package)(file_proto);

@@ -343,20 +343,17 @@ if (package.size) {

upb_StringView syntax = google_protobuf_FileDescriptorProto_syntax(file_proto);
// TODO: How should we validate this?
file->edition = UPB_DESC(FileDescriptorProto_edition)(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 (UPB_DESC(FileDescriptorProto_has_syntax)(file_proto)) {
upb_StringView syntax = UPB_DESC(FileDescriptorProto_syntax)(file_proto);
if (streql_view(syntax, "proto2")) {
file->edition = google_protobuf_EDITION_PROTO2;
file->syntax = kUpb_Syntax_Proto2;
file->edition = UPB_DESC(EDITION_PROTO2);
} else if (streql_view(syntax, "proto3")) {
file->edition = google_protobuf_EDITION_PROTO3;
file->syntax = kUpb_Syntax_Proto3;
file->edition = UPB_DESC(EDITION_PROTO3);
} else if (streql_view(syntax, "editions")) {
_upb_DefBuilder_Errf(
ctx, "File has syntax=\"editions\", but no edition is specified");
file->syntax = kUpb_Syntax_Editions;
file->edition = UPB_DESC(FileDescriptorProto_edition)(file_proto);
} else {

@@ -367,4 +364,4 @@ _upb_DefBuilder_Errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'",

} else {
// The legacy default when no edition or syntax is specified is proto2.
file->edition = google_protobuf_EDITION_PROTO2;
file->syntax = kUpb_Syntax_Proto2;
file->edition = UPB_DESC(EDITION_PROTO2);
}

@@ -376,5 +373,6 @@

// Resolve features.
const google_protobuf_FeatureSet* edition_defaults =
const UPB_DESC(FeatureSet*) edition_defaults =
_upb_FileDef_FindEdition(ctx, file->edition);
const google_protobuf_FeatureSet* unresolved = google_protobuf_FileOptions_features(file->opts);
const UPB_DESC(FeatureSet*) unresolved =
UPB_DESC(FileOptions_features)(file->opts);
file->resolved_features =

@@ -384,3 +382,3 @@ _upb_DefBuilder_ResolveFeatures(ctx, edition_defaults, unresolved);

// Verify dependencies.
strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
strs = UPB_DESC(FileDescriptorProto_dependency)(file_proto, &n);
file->dep_count = n;

@@ -401,3 +399,3 @@ file->deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const upb_FileDef*, n);

public_deps = google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n);
public_deps = UPB_DESC(FileDescriptorProto_public_dependency)(file_proto, &n);
file->public_dep_count = n;

@@ -414,3 +412,3 @@ file->public_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, int32_t, n);

weak_deps = google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n);
weak_deps = UPB_DESC(FileDescriptorProto_weak_dependency)(file_proto, &n);
file->weak_dep_count = n;

@@ -428,3 +426,3 @@ file->weak_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const int32_t, n);

// Create enums.
enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
enums = UPB_DESC(FileDescriptorProto_enum_type)(file_proto, &n);
file->top_lvl_enum_count = n;

@@ -435,3 +433,3 @@ file->top_lvl_enums =

// Create extensions.
exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
exts = UPB_DESC(FileDescriptorProto_extension)(file_proto, &n);
file->top_lvl_ext_count = n;

@@ -442,3 +440,3 @@ file->top_lvl_exts = _upb_Extensions_New(

// Create messages.
msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
msgs = UPB_DESC(FileDescriptorProto_message_type)(file_proto, &n);
file->top_lvl_msg_count = n;

@@ -449,3 +447,3 @@ file->top_lvl_msgs =

// Create services.
services = google_protobuf_FileDescriptorProto_service(file_proto, &n);
services = UPB_DESC(FileDescriptorProto_service)(file_proto, &n);
file->service_count = n;

@@ -452,0 +450,0 @@ file->services =

@@ -14,3 +14,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -30,6 +29,6 @@ // Must be last.

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 UPB_DESC(FileOptions) * upb_FileDef_Options(const upb_FileDef* f);
const UPB_DESC(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_DESC(Edition) upb_FileDef_Edition(const upb_FileDef* f);
UPB_API const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f);

@@ -43,2 +42,4 @@

UPB_API upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f);
const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i);

@@ -45,0 +46,0 @@ int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f);

@@ -10,22 +10,12 @@ // Protocol Buffers - Google's data interchange format

#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include "upb/base/internal/log2.h"
#include "upb/base/status.h"
#include "upb/base/string_view.h"
#include "upb/base/upcast.h"
#include "upb/hash/common.h"
#include "upb/hash/str_table.h"
#include "upb/mem/alloc.h"
#include "upb/mem/arena.h"
#include "upb/message/copy.h"
#include "upb/reflection/def.h"
#include "upb/reflection/def_pool.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/field_def.h"
#include "upb/reflection/file_def.h"
#include "upb/reflection/internal/def_pool.h"
#include "upb/reflection/internal/strdup2.h"

@@ -360,3 +350,3 @@ #include "upb/wire/decode.h"

upb_StringView _upb_DefBuilder_MakeKey(upb_DefBuilder* ctx,
const google_protobuf_FeatureSet* parent,
const UPB_DESC(FeatureSet*) parent,
upb_StringView key) {

@@ -376,5 +366,5 @@ size_t need = key.size + sizeof(void*);

bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx,
const google_protobuf_FeatureSet* parent,
const UPB_DESC(FeatureSet*) parent,
upb_StringView key,
google_protobuf_FeatureSet** set) {
UPB_DESC(FeatureSet**) set) {
upb_StringView k = _upb_DefBuilder_MakeKey(ctx, parent, key);

@@ -387,3 +377,3 @@ upb_value v;

*set = (google_protobuf_FeatureSet*)upb_Message_DeepClone(
*set = (UPB_DESC(FeatureSet*))upb_Message_DeepClone(
UPB_UPCAST(parent), UPB_DESC_MINITABLE(FeatureSet), ctx->arena);

@@ -401,17 +391,19 @@ if (!*set) _upb_DefBuilder_OomErr(ctx);

const google_protobuf_FeatureSet* _upb_DefBuilder_DoResolveFeatures(
upb_DefBuilder* ctx, const google_protobuf_FeatureSet* parent,
const google_protobuf_FeatureSet* child, bool is_implicit) {
const UPB_DESC(FeatureSet*)
_upb_DefBuilder_DoResolveFeatures(upb_DefBuilder* ctx,
const UPB_DESC(FeatureSet*) parent,
const UPB_DESC(FeatureSet*) child,
bool is_implicit) {
assert(parent);
if (!child) return parent;
if (!is_implicit &&
_upb_DefBuilder_IsLegacyEdition(upb_FileDef_Edition(ctx->file))) {
if (child && !is_implicit &&
upb_FileDef_Syntax(ctx->file) != kUpb_Syntax_Editions) {
_upb_DefBuilder_Errf(ctx, "Features can only be specified for editions");
}
google_protobuf_FeatureSet* resolved;
UPB_DESC(FeatureSet*) resolved;
size_t child_size;
const char* child_bytes =
google_protobuf_FeatureSet_serialize(child, ctx->tmp_arena, &child_size);
UPB_DESC(FeatureSet_serialize)(child, ctx->tmp_arena, &child_size);
if (!child_bytes) _upb_DefBuilder_OomErr(ctx);

@@ -418,0 +410,0 @@

@@ -25,3 +25,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_pool.h"

@@ -34,14 +33,13 @@

// 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; \
#define UPB_DEF_SET_OPTIONS(target, desc_type, options_type, proto) \
if (UPB_DESC(desc_type##_has_options)(proto)) { \
size_t size; \
char* pb = UPB_DESC(options_type##_serialize)( \
UPB_DESC(desc_type##_options)(proto), ctx->tmp_arena, &size); \
if (!pb) _upb_DefBuilder_OomErr(ctx); \
target = \
UPB_DESC(options_type##_parse)(pb, size, _upb_DefBuilder_Arena(ctx)); \
if (!target) _upb_DefBuilder_OomErr(ctx); \
} else { \
target = (const UPB_DESC(options_type)*)kUpbDefOptDefault; \
}

@@ -55,16 +53,16 @@

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.
upb_strtable feature_cache; // Caches features by identity.
UPB_DESC(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.
};

@@ -165,22 +163,18 @@

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,
const UPB_DESC(FeatureSet*) parent,
upb_StringView key,
google_protobuf_FeatureSet** set);
UPB_DESC(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);
const UPB_DESC(FeatureSet*)
_upb_DefBuilder_DoResolveFeatures(upb_DefBuilder* ctx,
const UPB_DESC(FeatureSet*) parent,
const UPB_DESC(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) {
UPB_INLINE const UPB_DESC(FeatureSet*)
_upb_DefBuilder_ResolveFeatures(upb_DefBuilder* ctx,
const UPB_DESC(FeatureSet*) parent,
const UPB_DESC(FeatureSet*) child) {
return _upb_DefBuilder_DoResolveFeatures(ctx, parent, child, false);

@@ -187,0 +181,0 @@ }

@@ -12,4 +12,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/mini_descriptor/decode.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/reflection/def.h"
#include "upb/reflection/def_pool.h"

@@ -53,5 +52,2 @@ // Must be last.

const upb_ExtensionRegistry* _upb_DefPool_GeneratedExtensionRegistry(
const upb_DefPool* s);
#ifdef __cplusplus

@@ -58,0 +54,0 @@ } /* extern "C" */

@@ -11,6 +11,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/mem/arena.h"
#include "upb/mini_table/enum.h"
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/enum_def.h"

@@ -30,4 +27,5 @@ // Must be last.

upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n,
const google_protobuf_EnumDescriptorProto* const* protos,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(EnumDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
const upb_MessageDef* containing_type);

@@ -34,0 +32,0 @@

@@ -11,4 +11,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/enum_reserved_range.h"

@@ -28,3 +27,3 @@ // Must be last.

upb_DefBuilder* ctx, int n,
const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* protos,
const UPB_DESC(EnumDescriptorProto_EnumReservedRange*) const* protos,
const upb_EnumDef* e);

@@ -31,0 +30,0 @@

@@ -11,8 +11,4 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include "upb/reflection/enum_value_def.h"
#include "upb/mem/arena.h"
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
// Must be last.

@@ -30,4 +26,5 @@ #include "upb/port/def.inc"

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_DESC(EnumValueDescriptorProto*) const* protos,
const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e,
bool* is_sorted);

@@ -34,0 +31,0 @@ const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v,

@@ -11,4 +11,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/extension_range.h"

@@ -27,4 +26,4 @@ // Must be last.

upb_DefBuilder* ctx, int n,
const google_protobuf_DescriptorProto_ExtensionRange* const* protos,
const google_protobuf_FeatureSet* parent_features, const upb_MessageDef* m);
const UPB_DESC(DescriptorProto_ExtensionRange*) const* protos,
const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* m);

@@ -31,0 +30,0 @@ #ifdef __cplusplus

@@ -11,8 +11,4 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include "upb/reflection/field_def.h"
#include "upb/mem/arena.h"
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
// Must be last.

@@ -37,14 +33,15 @@ #include "upb/port/def.inc"

// 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);
upb_FieldDef* _upb_Extensions_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(FieldDescriptorProto*)
const* protos,
const UPB_DESC(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);
upb_FieldDef* _upb_FieldDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(FieldDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
const char* prefix, upb_MessageDef* m,
bool* is_sorted);

@@ -51,0 +48,0 @@ // Allocate and return a list of pointers to the |n| field defs in |ff|,

@@ -11,7 +11,2 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include "upb/mini_table/extension.h"
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/file_def.h"

@@ -30,3 +25,2 @@

const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f);
bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f);

@@ -37,3 +31,3 @@ // upb_FileDef_Package() returns "" if f->package is NULL, this does not.

void _upb_FileDef_Create(upb_DefBuilder* ctx,
const google_protobuf_FileDescriptorProto* file_proto);
const UPB_DESC(FileDescriptorProto) * file_proto);

@@ -40,0 +34,0 @@ #ifdef __cplusplus

@@ -11,9 +11,4 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include "upb/reflection/message_def.h"
#include "upb/hash/common.h"
#include "upb/mem/arena.h"
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
// Must be last.

@@ -39,6 +34,8 @@ #include "upb/port/def.inc"

// 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_MessageDef* _upb_MessageDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(DescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*)
parent_features,
const upb_MessageDef* containing_type);

@@ -45,0 +42,0 @@ #ifdef __cplusplus

@@ -11,4 +11,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/message_reserved_range.h"

@@ -29,3 +27,3 @@

upb_DefBuilder* ctx, int n,
const google_protobuf_DescriptorProto_ReservedRange* const* protos,
const UPB_DESC(DescriptorProto_ReservedRange) * const* protos,
const upb_MessageDef* m);

@@ -32,0 +30,0 @@

@@ -11,4 +11,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/method_def.h"

@@ -25,6 +24,7 @@ // Must be last.

// 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);
upb_MethodDef* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(MethodDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
upb_ServiceDef* s);

@@ -31,0 +31,0 @@ #ifdef __cplusplus

@@ -11,4 +11,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/oneof_def.h"

@@ -27,6 +26,7 @@ // Must be last.

// 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);
upb_OneofDef* _upb_OneofDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(OneofDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
upb_MessageDef* m);

@@ -33,0 +33,0 @@ size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m);

@@ -11,4 +11,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/service_def.h"

@@ -25,6 +24,7 @@ // Must be last.

// 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);
upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(ServiceDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*)
parent_features);

@@ -31,0 +31,0 @@ #ifdef __cplusplus

@@ -23,11 +23,6 @@ // Protocol Buffers - Google's data interchange format

#include "upb/mini_descriptor/internal/modifiers.h"
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/file.h"
#include "upb/mini_table/message.h"
#include "upb/reflection/def.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"
#include "upb/reflection/internal/def_pool.h"
#include "upb/reflection/internal/desc_state.h"

@@ -46,4 +41,4 @@ #include "upb/reflection/internal/enum_def.h"

struct upb_MessageDef {
UPB_ALIGN_AS(8) const google_protobuf_MessageOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
UPB_ALIGN_AS(8) const UPB_DESC(MessageOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const upb_MiniTable* layout;

@@ -86,3 +81,3 @@ const upb_FileDef* file;

upb_WellKnown well_known_type;
google_protobuf_SymbolVisibility visibility;
UPB_DESC(SymbolVisibility) visibility;
};

@@ -147,3 +142,4 @@

const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m) {
const UPB_DESC(MessageOptions) *
upb_MessageDef_Options(const upb_MessageDef* m) {
return m->opts;

@@ -156,4 +152,4 @@ }

const google_protobuf_FeatureSet* upb_MessageDef_ResolvedFeatures(
const upb_MessageDef* m) {
const UPB_DESC(FeatureSet) *
upb_MessageDef_ResolvedFeatures(const upb_MessageDef* m) {
return m->resolved_features;

@@ -178,2 +174,6 @@ }

upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m) {
return upb_FileDef_Syntax(m->file);
}
const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m,

@@ -333,4 +333,4 @@ uint32_t i) {

UPB_API google_protobuf_SymbolVisibility
upb_MessageDef_Visibility(const upb_MessageDef* m) {
UPB_API UPB_DESC(SymbolVisibility)
upb_MessageDef_Visibility(const upb_MessageDef* m) {
return m->visibility;

@@ -354,7 +354,7 @@ }

bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) {
return google_protobuf_MessageOptions_map_entry(m->opts);
return UPB_DESC(MessageOptions_map_entry)(m->opts);
}
bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m) {
return google_protobuf_MessageOptions_message_set_wire_format(m->opts);
return UPB_DESC(MessageOptions_message_set_wire_format)(m->opts);
}

@@ -393,3 +393,3 @@

upb_FieldDef_MessageSubDef(ext) == m &&
google_protobuf_MessageOptions_message_set_wire_format(
UPB_DESC(MessageOptions_message_set_wire_format)(
upb_MessageDef_Options(upb_FieldDef_ContainingType(ext)))) {

@@ -431,7 +431,7 @@ m->in_message_set = true;

bool skip_json_conflicts =
google_protobuf_MessageOptions_deprecated_legacy_json_field_conflicts(
UPB_DESC(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_DESC(FeatureSet_json_format)(m->resolved_features) ==
UPB_DESC(FeatureSet_ALLOW) &&
upb_strtable_lookup(&m->ntof, json_name, &v)) {

@@ -492,3 +492,3 @@ _upb_DefBuilder_Errf(

if (ctx->layout || ctx->platform != kUpb_MiniTablePlatform_Native) return;
if (ctx->layout) return;

@@ -506,2 +506,5 @@ for (int i = 0; i < m->field_count; i++) {

if (sub_m) {
if (!mt->UPB_PRIVATE(subs)) {
_upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name);
}
UPB_ASSERT(mt_f);

@@ -662,3 +665,3 @@ UPB_ASSERT(sub_m->layout);

if (!_upb_MessageDef_EncodeMap(&s, m, a)) return false;
} else if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) {
} else if (UPB_DESC(MessageOptions_message_set_wire_format)(m->opts)) {
if (!_upb_MessageDef_EncodeMessageSet(&s, m, a)) return false;

@@ -689,10 +692,10 @@ } else {

static void create_msgdef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_DescriptorProto* msg_proto,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(DescriptorProto*) msg_proto,
const UPB_DESC(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_DESC(OneofDescriptorProto)* const* oneofs;
const UPB_DESC(FieldDescriptorProto)* const* fields;
const UPB_DESC(DescriptorProto_ExtensionRange)* const* ext_ranges;
const UPB_DESC(DescriptorProto_ReservedRange)* const* res_ranges;
const upb_StringView* res_names;

@@ -705,3 +708,3 @@ size_t n_oneof, n_field, n_enum, n_ext, n_msg;

m->resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_MessageOptions_features(m->opts));
ctx, parent_features, UPB_DESC(MessageOptions_features)(m->opts));

@@ -714,3 +717,3 @@ // Must happen before _upb_DefBuilder_Add()

name = google_protobuf_DescriptorProto_name(msg_proto);
name = UPB_DESC(DescriptorProto_name)(msg_proto);

@@ -720,7 +723,9 @@ m->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);

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);
oneofs = UPB_DESC(DescriptorProto_oneof_decl)(msg_proto, &n_oneof);
fields = UPB_DESC(DescriptorProto_field)(msg_proto, &n_field);
ext_ranges =
UPB_DESC(DescriptorProto_extension_range)(msg_proto, &n_ext_range);
res_ranges =
UPB_DESC(DescriptorProto_reserved_range)(msg_proto, &n_res_range);
res_names = UPB_DESC(DescriptorProto_reserved_name)(msg_proto, &n_res_name);

@@ -744,3 +749,3 @@ bool ok = upb_inttable_init(&m->itof, ctx->arena);

// Message Sets may not contain fields.
if (UPB_UNLIKELY(google_protobuf_MessageOptions_message_set_wire_format(m->opts))) {
if (UPB_UNLIKELY(UPB_DESC(MessageOptions_message_set_wire_format)(m->opts))) {
if (UPB_UNLIKELY(n_field > 0)) {

@@ -768,4 +773,4 @@ _upb_DefBuilder_Errf(ctx, "invalid message set (%s)", m->full_name);

const google_protobuf_EnumDescriptorProto* const* enums =
google_protobuf_DescriptorProto_enum_type(msg_proto, &n_enum);
const UPB_DESC(EnumDescriptorProto)* const* enums =
UPB_DESC(DescriptorProto_enum_type)(msg_proto, &n_enum);
m->nested_enum_count = n_enum;

@@ -775,4 +780,4 @@ m->nested_enums =

const google_protobuf_FieldDescriptorProto* const* exts =
google_protobuf_DescriptorProto_extension(msg_proto, &n_ext);
const UPB_DESC(FieldDescriptorProto)* const* exts =
UPB_DESC(DescriptorProto_extension)(msg_proto, &n_ext);
m->nested_ext_count = n_ext;

@@ -782,4 +787,4 @@ m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->resolved_features,

const google_protobuf_DescriptorProto* const* msgs =
google_protobuf_DescriptorProto_nested_type(msg_proto, &n_msg);
const UPB_DESC(DescriptorProto)* const* msgs =
UPB_DESC(DescriptorProto_nested_type)(msg_proto, &n_msg);
m->nested_msg_count = n_msg;

@@ -789,10 +794,12 @@ m->nested_msgs =

m->visibility = google_protobuf_DescriptorProto_visibility(msg_proto);
m->visibility = UPB_DESC(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_MessageDef* _upb_MessageDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(DescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*)
parent_features,
const upb_MessageDef* containing_type) {
_upb_DefType_CheckPadding(sizeof(upb_MessageDef));

@@ -799,0 +806,0 @@

@@ -15,3 +15,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -139,5 +138,6 @@ // Must be last.

const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m);
const google_protobuf_FeatureSet* upb_MessageDef_ResolvedFeatures(
const upb_MessageDef* m);
const UPB_DESC(MessageOptions) *
upb_MessageDef_Options(const upb_MessageDef* m);
const UPB_DESC(FeatureSet) *
upb_MessageDef_ResolvedFeatures(const upb_MessageDef* m);

@@ -151,5 +151,6 @@ upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i);

UPB_API upb_Syntax upb_MessageDef_Syntax(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);
UPB_API UPB_DESC(SymbolVisibility)
upb_MessageDef_Visibility(const upb_MessageDef* m);

@@ -156,0 +157,0 @@ #ifdef __cplusplus

@@ -8,8 +8,6 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include "upb/reflection/def.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/enum_def.h"
#include "upb/reflection/field_def.h"
#include "upb/reflection/internal/def_builder.h"
#include "upb/reflection/internal/extension_range.h"
#include "upb/reflection/message_def.h"

@@ -39,3 +37,3 @@

upb_DefBuilder* ctx, int n,
const google_protobuf_DescriptorProto_ReservedRange* const* protos,
const UPB_DESC(DescriptorProto_ReservedRange) * const* protos,
const upb_MessageDef* m) {

@@ -46,4 +44,5 @@ upb_MessageReservedRange* r =

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 start =
UPB_DESC(DescriptorProto_ReservedRange_start)(protos[i]);
const int32_t end = UPB_DESC(DescriptorProto_ReservedRange_end)(protos[i]);
const int32_t max = kUpb_MaxFieldNumber + 1;

@@ -50,0 +49,0 @@

@@ -10,6 +10,3 @@ // Protocol Buffers - Google's data interchange format

#include "upb/base/string_view.h"
#include "upb/reflection/def.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"

@@ -22,4 +19,4 @@ #include "upb/reflection/service_def.h"

struct upb_MethodDef {
const google_protobuf_MethodOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
const UPB_DESC(MethodOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
upb_ServiceDef* service;

@@ -42,3 +39,3 @@ const char* full_name;

const google_protobuf_MethodOptions* upb_MethodDef_Options(const upb_MethodDef* m) {
const UPB_DESC(MethodOptions) * upb_MethodDef_Options(const upb_MethodDef* m) {
return m->opts;

@@ -51,4 +48,4 @@ }

const google_protobuf_FeatureSet* upb_MethodDef_ResolvedFeatures(
const upb_MethodDef* m) {
const UPB_DESC(FeatureSet) *
upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m) {
return m->resolved_features;

@@ -84,4 +81,4 @@ }

static void create_method(upb_DefBuilder* ctx,
const google_protobuf_MethodDescriptorProto* method_proto,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(MethodDescriptorProto*) method_proto,
const UPB_DESC(FeatureSet*) parent_features,
upb_ServiceDef* s, upb_MethodDef* m) {

@@ -91,5 +88,5 @@ UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions,

m->resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_MethodOptions_features(m->opts));
ctx, parent_features, UPB_DESC(MethodOptions_features)(m->opts));
upb_StringView name = google_protobuf_MethodDescriptorProto_name(method_proto);
upb_StringView name = UPB_DESC(MethodDescriptorProto_name)(method_proto);

@@ -100,18 +97,21 @@ m->service = s;

m->client_streaming =
google_protobuf_MethodDescriptorProto_client_streaming(method_proto);
UPB_DESC(MethodDescriptorProto_client_streaming)(method_proto);
m->server_streaming =
google_protobuf_MethodDescriptorProto_server_streaming(method_proto);
UPB_DESC(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);
UPB_DESC(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_DESC(MethodDescriptorProto_output_type)(method_proto),
UPB_DEFTYPE_MSG);
}
// 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* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(MethodDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
upb_ServiceDef* s) {
upb_MethodDef* m = UPB_DEFBUILDER_ALLOCARRAY(ctx, upb_MethodDef, n);

@@ -118,0 +118,0 @@ for (int i = 0; i < n; i++) {

@@ -14,3 +14,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -30,5 +29,6 @@ // Must be last.

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_DESC(MethodOptions) *
upb_MethodDef_Options(const upb_MethodDef* m);
const UPB_DESC(FeatureSet) *
upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m);
UPB_API const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m);

@@ -35,0 +35,0 @@ UPB_API bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m);

@@ -10,13 +10,9 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "upb/base/string_view.h"
#include "upb/hash/common.h"
#include "upb/hash/int_table.h"
#include "upb/hash/str_table.h"
#include "upb/reflection/def.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"

@@ -30,4 +26,4 @@ #include "upb/reflection/internal/field_def.h"

struct upb_OneofDef {
UPB_ALIGN_AS(8) const google_protobuf_OneofOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
UPB_ALIGN_AS(8) const UPB_DESC(OneofOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const upb_MessageDef* parent;

@@ -46,3 +42,3 @@ const char* full_name;

const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o) {
const UPB_DESC(OneofOptions) * upb_OneofDef_Options(const upb_OneofDef* o) {
return o->opts;

@@ -55,3 +51,4 @@ }

const google_protobuf_FeatureSet* upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o) {
const UPB_DESC(FeatureSet) *
upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o) {
return o->resolved_features;

@@ -179,4 +176,4 @@ }

static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m,
const google_protobuf_OneofDescriptorProto* oneof_proto,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(OneofDescriptorProto*) oneof_proto,
const UPB_DESC(FeatureSet*) parent_features,
const upb_OneofDef* _o) {

@@ -187,5 +184,5 @@ upb_OneofDef* o = (upb_OneofDef*)_o;

o->resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_OneofOptions_features(o->opts));
ctx, parent_features, UPB_DESC(OneofOptions_features)(o->opts));
upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
upb_StringView name = UPB_DESC(OneofDescriptorProto_name)(oneof_proto);

@@ -214,6 +211,7 @@ o->parent = m;

// 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_OneofDef* _upb_OneofDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(OneofDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*) parent_features,
upb_MessageDef* m) {
_upb_DefType_CheckPadding(sizeof(upb_OneofDef));

@@ -220,0 +218,0 @@

@@ -13,7 +13,3 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include <stdint.h>
#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -44,4 +40,5 @@ // Must be last.

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);
const UPB_DESC(OneofOptions*) upb_OneofDef_Options(const upb_OneofDef* o);
const UPB_DESC(FeatureSet*)
upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o);

@@ -48,0 +45,0 @@ #ifdef __cplusplus

@@ -10,9 +10,3 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include <string.h>
#include "upb/base/string_view.h"
#include "upb/reflection/def.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb/reflection/internal/def_builder.h"

@@ -26,4 +20,4 @@ #include "upb/reflection/internal/file_def.h"

struct upb_ServiceDef {
UPB_ALIGN_AS(8) const google_protobuf_ServiceOptions* opts;
const google_protobuf_FeatureSet* resolved_features;
UPB_ALIGN_AS(8) const UPB_DESC(ServiceOptions*) opts;
const UPB_DESC(FeatureSet*) resolved_features;
const upb_FileDef* file;

@@ -40,3 +34,4 @@ const char* full_name;

const google_protobuf_ServiceOptions* upb_ServiceDef_Options(const upb_ServiceDef* s) {
const UPB_DESC(ServiceOptions) *
upb_ServiceDef_Options(const upb_ServiceDef* s) {
return s->opts;

@@ -49,4 +44,4 @@ }

const google_protobuf_FeatureSet* upb_ServiceDef_ResolvedFeatures(
const upb_ServiceDef* s) {
const UPB_DESC(FeatureSet) *
upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s) {
return s->resolved_features;

@@ -90,4 +85,4 @@ }

static void create_service(upb_DefBuilder* ctx,
const google_protobuf_ServiceDescriptorProto* svc_proto,
const google_protobuf_FeatureSet* parent_features,
const UPB_DESC(ServiceDescriptorProto*) svc_proto,
const UPB_DESC(FeatureSet*) parent_features,
upb_ServiceDef* s) {

@@ -97,3 +92,3 @@ UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions,

s->resolved_features = _upb_DefBuilder_ResolveFeatures(
ctx, parent_features, google_protobuf_ServiceOptions_features(s->opts));
ctx, parent_features, UPB_DESC(ServiceOptions_features)(s->opts));

@@ -103,3 +98,3 @@ // Must happen before _upb_DefBuilder_Add()

upb_StringView name = google_protobuf_ServiceDescriptorProto_name(svc_proto);
upb_StringView name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto);
const char* package = _upb_FileDef_RawPackage(s->file);

@@ -111,4 +106,4 @@ s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name);

size_t n;
const google_protobuf_MethodDescriptorProto* const* methods =
google_protobuf_ServiceDescriptorProto_method(svc_proto, &n);
const UPB_DESC(MethodDescriptorProto)* const* methods =
UPB_DESC(ServiceDescriptorProto_method)(svc_proto, &n);
s->method_count = n;

@@ -118,6 +113,7 @@ 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_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n,
const UPB_DESC(ServiceDescriptorProto*)
const* protos,
const UPB_DESC(FeatureSet*)
parent_features) {
_upb_DefType_CheckPadding(sizeof(upb_ServiceDef));

@@ -124,0 +120,0 @@

@@ -14,3 +14,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/reflection/common.h"
#include "upb/reflection/descriptor_bootstrap.h"

@@ -34,6 +33,6 @@ // Must be last.

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);
UPB_API const UPB_DESC(ServiceOptions) *
upb_ServiceDef_Options(const upb_ServiceDef* s);
const UPB_DESC(FeatureSet) *
upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s);

@@ -40,0 +39,0 @@ #ifdef __cplusplus

@@ -62,3 +62,3 @@ // Protocol Buffers - Google's data interchange format

const upb_MiniTable* subm = ext ? upb_MiniTableExtension_GetSubMessage(ext)
: upb_MiniTable_SubMessage(f);
: upb_MiniTable_SubMessage(mt, f);
_upb_MessageDebugString(e, val.msg_val, subm);

@@ -105,3 +105,3 @@ e->indent_depth--;

const upb_MiniTable* mt) {
const upb_MiniTable* entry = upb_MiniTable_SubMessage(f);
const upb_MiniTable* entry = upb_MiniTable_SubMessage(mt, f);
const upb_MiniTableField* key_f = upb_MiniTable_MapKey(entry);

@@ -148,3 +148,3 @@ const upb_MiniTableField* val_f = upb_MiniTable_MapValue(entry);

const upb_MiniTable* entry = upb_MiniTable_SubMessage(f);
const upb_MiniTable* entry = upb_MiniTable_SubMessage(mt, f);
const upb_MiniTableField* key_f = upb_MiniTable_GetFieldByIndex(entry, 0);

@@ -151,0 +151,0 @@ _upb_sortedmap sorted;

@@ -86,6 +86,4 @@ // Protocol Buffers - Google's data interchange format

size_t start_overflow = e->overflow;
upb_StringView sv;
CHK(ptr = upb_WireReader_ReadSize(ptr, &size, stream));
CHK(ptr = upb_EpsCopyInputStream_ReadStringAlwaysAlias(stream, ptr,
size, &sv));
CHK(upb_EpsCopyInputStream_CheckDataSizeAvailable(stream, ptr, size));

@@ -99,7 +97,8 @@ // Speculatively try to parse as message.

upb_EpsCopyInputStream sub_stream;
const char* sub_ptr = sv.data;
upb_EpsCopyInputStream_Init(&sub_stream, &sub_ptr, size);
const char* sub_ptr = upb_EpsCopyInputStream_GetAliasedPtr(stream, ptr);
upb_EpsCopyInputStream_Init(&sub_stream, &sub_ptr, size, true);
e->indent_depth++;
if (UPB_PRIVATE(_upb_TextEncode_Unknown)(e, sub_ptr, &sub_stream, -1)) {
ptr = upb_EpsCopyInputStream_Skip(stream, ptr, size);
e->indent_depth--;

@@ -113,3 +112,7 @@ UPB_PRIVATE(_upb_TextEncode_Indent)(e);

e->overflow = start_overflow;
UPB_PRIVATE(_upb_TextEncode_Bytes)(e, sv);
const char* str = ptr;
ptr = upb_EpsCopyInputStream_ReadString(stream, &str, size, NULL);
UPB_ASSERT(ptr);
UPB_PRIVATE(_upb_TextEncode_Bytes)
(e, (upb_StringView){.data = str, .size = size});
}

@@ -148,3 +151,3 @@ break;

upb_EpsCopyInputStream stream;
upb_EpsCopyInputStream_Init(&stream, &view.data, view.size);
upb_EpsCopyInputStream_Init(&stream, &view.data, view.size, true);
if (!UPB_PRIVATE(_upb_TextEncode_Unknown)(e, view.data, &stream, -1)) {

@@ -151,0 +154,0 @@ /* Unknown failed to parse, back up and don't print it at all. */

@@ -12,13 +12,5 @@ // Protocol Buffers - Google's data interchange format

#include <math.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "google/protobuf/descriptor.upb.h"
#include "upb/base/descriptor_constants.h"
#include "upb/base/string_view.h"
#include "upb/mem/arena.h"
#include "upb/message/array.h"
#include "upb/port/vsnprintf_compat.h"

@@ -28,5 +20,5 @@ #include "upb/reflection/def.h"

#include "upb/reflection/extension_range.h"
#include "upb/reflection/internal/def_pool.h"
#include "upb/reflection/internal/field_def.h"
#include "upb/reflection/internal/file_def.h"
#include "upb/reflection/message.h"
#include "upb/reflection/message_reserved_range.h"

@@ -47,12 +39,12 @@

// 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); \
#define SET_OPTIONS(proto, desc_type, options_type, src) \
{ \
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(pb, size, ctx->arena); \
CHK_OOM(dst); \
google_protobuf_##desc_type##_set_options(proto, dst); \
}

@@ -237,5 +229,5 @@

if (upb_FieldDef_IsRequired(f) &&
upb_FileDef_Edition(upb_FieldDef_File(f)) >= google_protobuf_EDITION_2023) {
upb_FileDef_Edition(upb_FieldDef_File(f)) >= UPB_DESC(EDITION_2023)) {
google_protobuf_FieldDescriptorProto_set_label(
proto, google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL);
proto, UPB_DESC(FieldDescriptorProto_LABEL_OPTIONAL));
} else {

@@ -245,3 +237,3 @@ 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) {
upb_FileDef_Edition(upb_FieldDef_File(f)) >= UPB_DESC(EDITION_2023)) {
google_protobuf_FieldDescriptorProto_set_type(proto, kUpb_FieldType_Message);

@@ -288,5 +280,3 @@ } else {

SET_OPTIONS(proto, FieldDescriptorProto, FieldOptions,
upb_FieldDef_Options(f),
_upb_DefPool_GeneratedExtensionRegistry(
upb_FileDef_Pool(upb_FieldDef_File(f))));
upb_FieldDef_Options(f));
}

@@ -308,5 +298,3 @@

SET_OPTIONS(proto, OneofDescriptorProto, OneofOptions,
upb_OneofDef_Options(o),
_upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool(
upb_MessageDef_File(upb_OneofDef_ContainingType(o)))));
upb_OneofDef_Options(o));
}

@@ -329,5 +317,3 @@

SET_OPTIONS(proto, EnumValueDescriptorProto, EnumValueOptions,
upb_EnumValueDef_Options(e),
_upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool(
upb_EnumDef_File(upb_EnumValueDef_Enum(e)))));
upb_EnumValueDef_Options(e));
}

@@ -370,9 +356,8 @@

if (upb_EnumDef_HasOptions(e)) {
SET_OPTIONS(proto, EnumDescriptorProto, EnumOptions, upb_EnumDef_Options(e),
_upb_DefPool_GeneratedExtensionRegistry(
upb_FileDef_Pool(upb_EnumDef_File(e))));
SET_OPTIONS(proto, EnumDescriptorProto, EnumOptions,
upb_EnumDef_Options(e));
}
google_protobuf_SymbolVisibility visibility = upb_EnumDef_Visibility(e);
if (visibility != google_protobuf_VISIBILITY_UNSET) {
UPB_DESC(SymbolVisibility) visibility = upb_EnumDef_Visibility(e);
if (visibility != UPB_DESC(VISIBILITY_UNSET)) {
google_protobuf_EnumDescriptorProto_set_visibility(proto, visibility);

@@ -385,4 +370,3 @@ }

static google_protobuf_DescriptorProto_ExtensionRange* extrange_toproto(
upb_ToProto_Context* ctx, const upb_MessageDef* m,
const upb_ExtensionRange* e) {
upb_ToProto_Context* ctx, const upb_ExtensionRange* e) {
google_protobuf_DescriptorProto_ExtensionRange* proto =

@@ -399,5 +383,3 @@ google_protobuf_DescriptorProto_ExtensionRange_new(ctx->arena);

SET_OPTIONS(proto, DescriptorProto_ExtensionRange, ExtensionRangeOptions,
upb_ExtensionRange_Options(e),
_upb_DefPool_GeneratedExtensionRegistry(
upb_FileDef_Pool(upb_MessageDef_File(m))));
upb_ExtensionRange_Options(e));
}

@@ -459,4 +441,3 @@

for (int i = 0; i < n; i++) {
ext_ranges[i] =
extrange_toproto(ctx, m, upb_MessageDef_ExtensionRange(m, i));
ext_ranges[i] = extrange_toproto(ctx, upb_MessageDef_ExtensionRange(m, i));
}

@@ -480,9 +461,7 @@

SET_OPTIONS(proto, DescriptorProto, MessageOptions,
upb_MessageDef_Options(m),
_upb_DefPool_GeneratedExtensionRegistry(
upb_FileDef_Pool(upb_MessageDef_File(m))));
upb_MessageDef_Options(m));
}
google_protobuf_SymbolVisibility visibility = upb_MessageDef_Visibility(m);
if (visibility != google_protobuf_VISIBILITY_UNSET) {
UPB_DESC(SymbolVisibility) visibility = upb_MessageDef_Visibility(m);
if (visibility != UPB_DESC(VISIBILITY_UNSET)) {
google_protobuf_DescriptorProto_set_visibility(proto, visibility);

@@ -519,6 +498,4 @@ }

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)))));
SET_OPTIONS(proto, MethodDescriptorProto, MethodOptions,
upb_MethodDef_Options(m));
}

@@ -547,5 +524,3 @@

SET_OPTIONS(proto, ServiceDescriptorProto, ServiceOptions,
upb_ServiceDef_Options(s),
_upb_DefPool_GeneratedExtensionRegistry(
upb_FileDef_Pool(upb_ServiceDef_File(s))));
upb_ServiceDef_Options(s));
}

@@ -573,16 +548,10 @@

google_protobuf_Edition edition = upb_FileDef_Edition(f);
if (upb_FileDef_Syntax(f) == kUpb_Syntax_Editions) {
google_protobuf_FileDescriptorProto_set_edition(proto, 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;
if (upb_FileDef_Syntax(f) == kUpb_Syntax_Proto3) {
google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "proto3"));
} else if (upb_FileDef_Syntax(f) == kUpb_Syntax_Editions) {
google_protobuf_FileDescriptorProto_set_syntax(proto, strviewdup(ctx, "editions"));
}

@@ -639,4 +608,4 @@

if (upb_FileDef_HasOptions(f)) {
SET_OPTIONS(proto, FileDescriptorProto, FileOptions, upb_FileDef_Options(f),
_upb_DefPool_GeneratedExtensionRegistry(upb_FileDef_Pool(f)));
SET_OPTIONS(proto, FileDescriptorProto, FileOptions,
upb_FileDef_Options(f));
}

@@ -643,0 +612,0 @@

@@ -17,3 +17,2 @@ // Protocol Buffers - Google's data interchange format

#include "upb/base/descriptor_constants.h"
#include "upb/base/error_handler.h"
#include "upb/base/internal/endian.h"

@@ -30,4 +29,6 @@ #include "upb/base/string_view.h"

#include "upb/message/internal/message.h"
#include "upb/message/internal/tagged_ptr.h"
#include "upb/message/map.h"
#include "upb/message/message.h"
#include "upb/message/tagged_ptr.h"
#include "upb/mini_table/enum.h"

@@ -101,8 +102,29 @@ #include "upb/mini_table/extension.h"

static void _upb_Decoder_AssumeEpsHasErrorHandler(upb_Decoder* d) {
UPB_ASSUME(upb_EpsCopyInputStream_HasErrorHandler(&d->input));
// Ideally these two functions should take the owning MiniTable pointer as a
// first argument, then we could just put them in mini_table/message.h as nice
// clean getters. But we don't have that so instead we gotta write these
// Frankenfunctions that take an array of subtables.
// TODO: Move these to mini_table/ anyway since there are other places
// that could use them.
// Returns the MiniTable corresponding to a given MiniTableField
// from an array of MiniTableSubs.
static const upb_MiniTable* _upb_MiniTableSubs_MessageByField(
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field) {
return *subs[field->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(submsg);
}
#define EPS(d) (_upb_Decoder_AssumeEpsHasErrorHandler(d), &(d)->input)
// Returns the MiniTableEnum corresponding to a given MiniTableField
// from an array of MiniTableSub.
static const upb_MiniTableEnum* _upb_MiniTableSubs_EnumByField(
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field) {
return subs[field->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(subenum);
}
static void _upb_Decoder_VerifyUtf8(upb_Decoder* d, const char* buf, int len) {
if (!_upb_Decoder_VerifyUtf8Inline(buf, len)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_BadUtf8);
}
}
static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {

@@ -113,3 +135,3 @@ bool need_realloc =

arr, arr->UPB_PRIVATE(size) + elem, &d->arena)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}

@@ -124,10 +146,75 @@ return need_realloc;

// This is identical to _upb_Decoder_DecodeTag() except that the maximum value
// is INT32_MAX instead of UINT32_MAX.
UPB_NOINLINE
static _upb_DecodeLongVarintReturn _upb_Decoder_DecodeLongVarint(
const char* ptr, uint64_t val, upb_Decoder* d) {
uint64_t byte;
for (int i = 1; i < 10; i++) {
byte = (uint8_t)ptr[i];
val += (byte - 1) << (i * 7);
if (!(byte & 0x80)) {
return (_upb_DecodeLongVarintReturn){.ptr = ptr + i + 1, .val = val};
}
}
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
UPB_NOINLINE
static _upb_DecodeLongVarintReturn _upb_Decoder_DecodeLongTag(const char* ptr,
uint64_t val,
upb_Decoder* d) {
uint64_t byte;
for (int i = 1; i < 5; i++) {
byte = (uint8_t)ptr[i];
val += (byte - 1) << (i * 7);
if (!(byte & 0x80)) {
if (val > UINT32_MAX) {
break;
}
return (_upb_DecodeLongVarintReturn){.ptr = ptr + i + 1, .val = val};
}
}
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
UPB_FORCEINLINE
const char* _upb_Decoder_DecodeVarint(upb_Decoder* d, const char* ptr,
uint64_t* val) {
UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(&d->input, 10);
uint64_t byte = (uint8_t)*ptr;
if (UPB_LIKELY((byte & 0x80) == 0)) {
*val = byte;
return ptr + 1;
} else {
_upb_DecodeLongVarintReturn res =
_upb_Decoder_DecodeLongVarint(ptr, byte, d);
*val = res.val;
return res.ptr;
}
}
UPB_FORCEINLINE
const char* _upb_Decoder_DecodeTag(upb_Decoder* d, const char* ptr,
uint32_t* val) {
UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(&d->input, 5);
uint64_t byte = (uint8_t)*ptr;
if (UPB_LIKELY((byte & 0x80) == 0)) {
*val = byte;
return ptr + 1;
} else {
_upb_DecodeLongVarintReturn res = _upb_Decoder_DecodeLongTag(ptr, byte, d);
*val = res.val;
return res.ptr;
}
}
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;
uint64_t size64;
ptr = _upb_Decoder_DecodeVarint(d, ptr, &size64);
if (size64 >= INT32_MAX ||
!upb_EpsCopyInputStream_CheckSize(&d->input, ptr, (int)size64)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
*size = size64;
return ptr;

@@ -170,24 +257,65 @@ }

const upb_MiniTableField* field,
upb_Message** target) {
upb_TaggedMessagePtr* target) {
UPB_ASSERT(subl);
upb_Message* msg = _upb_Message_New(subl, &d->arena);
if (!msg) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
*target = msg;
// Extensions should not be unlinked. A message extension should not be
// registered until its sub-message type is available to be linked.
bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl);
bool is_extension = field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension;
UPB_ASSERT(!(is_empty && is_extension));
if (is_empty && !(d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_UnlinkedSubMessage);
}
upb_TaggedMessagePtr tagged =
UPB_PRIVATE(_upb_TaggedMessagePtr_Pack)(msg, is_empty);
memcpy(target, &tagged, sizeof(tagged));
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);
static upb_Message* _upb_Decoder_NewSubMessage(
upb_Decoder* d, const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field, upb_TaggedMessagePtr* target) {
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, 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);
static upb_Message* _upb_Decoder_ReuseSubMessage(
upb_Decoder* d, const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field, upb_TaggedMessagePtr* target) {
upb_TaggedMessagePtr tagged = *target;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
if (!upb_TaggedMessagePtr_IsEmpty(tagged) ||
UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) {
return UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(tagged);
}
// We found an empty message from a previous parse that was performed before
// this field was linked. But it is linked now, so we want to allocate a new
// message of the correct type and promote data into it before continuing.
upb_Message* existing =
UPB_PRIVATE(_upb_TaggedMessagePtr_GetEmptyMessage)(tagged);
upb_Message* promoted = _upb_Decoder_NewSubMessage(d, subs, field, target);
uintptr_t iter = kUpb_Message_UnknownBegin;
upb_StringView unknown;
while (upb_Message_NextUnknown(existing, &unknown, &iter)) {
upb_DecodeStatus status =
upb_Decode(unknown.data, unknown.size, promoted, subl, d->extreg,
d->options, &d->arena);
if (status != kUpb_DecodeStatus_Ok) _upb_Decoder_ErrorJmp(d, status);
}
return promoted;
}
static const char* _upb_Decoder_ReadString(upb_Decoder* d, const char* ptr,
int size, upb_StringView* str) {
const char* str_ptr = ptr;
ptr = upb_EpsCopyInputStream_ReadString(&d->input, &str_ptr, size, &d->arena);
if (!ptr) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
str->data = str_ptr;
str->size = size;
return ptr;

@@ -202,3 +330,3 @@ }

if (--d->depth < 0) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_MaxDepthExceeded);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_MaxDepthExceeded);
}

@@ -208,3 +336,3 @@ ptr = _upb_Decoder_DecodeMessage(d, ptr, submsg, subl);

if (d->end_group != expected_end_group) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}

@@ -217,9 +345,10 @@ return ptr;

upb_Message* submsg,
const upb_MiniTableSubInternal* subs,
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);
int size) {
int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size);
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP);
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta);
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_delta);
return ptr;

@@ -233,4 +362,4 @@ }

uint32_t number) {
if (upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
if (_upb_Decoder_IsDone(d, &ptr)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}

@@ -243,6 +372,13 @@ ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, number);

UPB_FORCEINLINE
const char* _upb_Decoder_DecodeUnknownGroup(upb_Decoder* d, const char* ptr,
uint32_t number) {
return _upb_Decoder_DecodeGroup(d, ptr, NULL, NULL, number);
}
UPB_FORCEINLINE
const char* _upb_Decoder_DecodeKnownGroup(upb_Decoder* d, const char* ptr,
upb_Message* submsg,
const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field) {
const upb_MiniTable* subl = upb_MiniTable_GetSubMessageTable(field);
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);

@@ -282,4 +418,4 @@ return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl,

if (!UPB_PRIVATE(_upb_Message_AddUnknown)(unknown_msg, buf, end - buf,
&d->arena, kUpb_AddUnknown_Copy)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
&d->arena, NULL)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}

@@ -293,12 +429,8 @@ }

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 ((val->size & mask) != 0) {
// Length isn't a round multiple of elem size.
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
size_t count = val->size >> lg2;
if (count == 0) return ptr;
_upb_Decoder_Reserve(d, arr, count);

@@ -308,24 +440,20 @@ void* mem = UPB_PTR_AT(upb_Array_MutableDataPtr(arr),

arr->UPB_PRIVATE(size) += count;
// Note: if/when the decoder supports multi-buffer input, we will need to
// handle buffer seams here.
if (upb_IsLittleEndian()) {
memcpy(mem, sv.data, sv.size);
ptr = upb_EpsCopyInputStream_Copy(&d->input, ptr, mem, val->size);
} else {
const char* src = sv.data;
const char* src_end = src + sv.size;
int delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->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);
while (!_upb_Decoder_IsDone(d, &ptr)) {
if (lg2 == 2) {
ptr = upb_WireReader_ReadFixed32(ptr, dst, &d->input);
dst += 4;
} else {
UPB_ASSERT(lg2 == 3);
ptr = upb_WireReader_ReadFixed64(ptr, dst, &d->input);
dst += 8;
}
} 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);
}
}
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta);
}

@@ -342,8 +470,8 @@

int scale = 1 << lg2;
ptrdiff_t delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size);
int saved_limit = 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)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
wireval elem;
ptr = upb_WireReader_ReadVarint(ptr, &elem.uint64_val, EPS(d));
ptr = _upb_Decoder_DecodeVarint(d, ptr, &elem.uint64_val);
_upb_Decoder_Munge(field, &elem);

@@ -358,3 +486,3 @@ if (_upb_Decoder_Reserve(d, arr, 1)) {

}
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta);
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_limit);
return ptr;

@@ -366,10 +494,11 @@ }

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);
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val) {
const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field);
int saved_limit = 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)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
wireval elem;
ptr = upb_WireReader_ReadVarint(ptr, &elem.uint64_val, EPS(d));
ptr = _upb_Decoder_DecodeVarint(d, ptr, &elem.uint64_val);
if (!upb_MiniTableEnum_CheckValue(e, elem.uint64_val)) {

@@ -387,3 +516,3 @@ _upb_Decoder_AddEnumValueToUnknown(d, msg, field, &elem);

}
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, delta);
upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_limit);
return ptr;

@@ -397,10 +526,10 @@ }

upb_Array* ret = UPB_PRIVATE(_upb_Array_New)(&d->arena, 4, lg2);
if (!ret) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
if (!ret) _upb_Decoder_ErrorJmp(d, 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) {
static const char* _upb_Decoder_DecodeToArray(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val, int op) {
upb_Array** arrp = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void);

@@ -427,11 +556,5 @@ upb_Array* arr = *arrp;

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_String:
_upb_Decoder_VerifyUtf8(d, ptr, val->size);
/* Fallthrough. */
case kUpb_DecodeOp_Bytes: {

@@ -441,19 +564,18 @@ /* Append bytes. */

arr->UPB_PRIVATE(size);
ptr = _upb_Decoder_ReadString2(d, ptr, val->size, str,
/*validate_utf8=*/false);
arr->UPB_PRIVATE(size)++;
return ptr;
return _upb_Decoder_ReadString(d, ptr, val->size, str);
}
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);
upb_TaggedMessagePtr* target = UPB_PTR_AT(
upb_Array_MutableDataPtr(arr), arr->UPB_PRIVATE(size) * sizeof(void*),
upb_TaggedMessagePtr);
upb_Message* submsg = _upb_Decoder_NewSubMessage(d, subs, field, target);
arr->UPB_PRIVATE(size)++;
if (UPB_UNLIKELY(field->UPB_PRIVATE(descriptortype) ==
kUpb_FieldType_Group)) {
return _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, field);
return _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, subs, field);
} else {
return _upb_Decoder_DecodeSubMessage(d, ptr, submsg, field, val->size);
return _upb_Decoder_DecodeSubMessage(d, ptr, submsg, subs, field,
val->size);
}

@@ -471,3 +593,3 @@ }

case kUpb_DecodeOp_PackedEnum:
return _upb_Decoder_DecodeEnumPacked(d, ptr, msg, arr, field, val);
return _upb_Decoder_DecodeEnumPacked(d, ptr, msg, arr, subs, field, val);
default:

@@ -510,3 +632,3 @@ UPB_UNREACHABLE();

upb_Map* ret = _upb_Map_New(&d->arena, key_size, val_size);
if (!ret) upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
if (!ret) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
return ret;

@@ -523,3 +645,3 @@ }

if (status != kUpb_EncodeStatus_Ok) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}

@@ -538,10 +660,10 @@ char delim_buf[2 * kUpb_Decoder_EncodeVarint32MaxSize];

if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 2)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
}
static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTableField* field,
wireval* val) {
static const char* _upb_Decoder_DecodeToMap(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val) {
upb_Map** map_p = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), upb_Map*);

@@ -551,3 +673,3 @@ upb_Map* map = *map_p;

UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message);
const upb_MiniTable* entry = upb_MiniTable_GetSubMessageTable(field);
const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field);

@@ -567,28 +689,15 @@ UPB_ASSERT(entry);

bool value_is_message =
entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) ==
if (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) {
kUpb_FieldType_Group) {
// 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);
upb_TaggedMessagePtr msg;
_upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs),
&entry->UPB_PRIVATE(fields)[1], &msg);
ent.v.val = upb_value_uintptr(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);
}
ptr = _upb_Decoder_DecodeSubMessage(d, ptr, &ent.message, subs, field,
val->size);
if (upb_Message_HasUnknown(&ent.message)) {

@@ -599,3 +708,3 @@ _upb_Decoder_AddMapEntryUnknown(d, msg, field, &ent.message, entry);

&d->arena) == kUpb_MapInsertStatus_OutOfMemory) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}

@@ -608,3 +717,4 @@ }

upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTableField* field, wireval* val, int op) {
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field,
wireval* val, int op) {
void* mem = UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void);

@@ -629,9 +739,14 @@ int type = field->UPB_PRIVATE(descriptortype);

case kUpb_DecodeOp_SubMessage: {
upb_Message** submsgp = mem;
upb_Message* submsg = *submsgp;
if (!submsg) submsg = _upb_Decoder_NewSubMessage(d, field, submsgp);
upb_TaggedMessagePtr* submsgp = mem;
upb_Message* submsg;
if (*submsgp) {
submsg = _upb_Decoder_ReuseSubMessage(d, subs, field, submsgp);
} else {
submsg = _upb_Decoder_NewSubMessage(d, subs, field, submsgp);
}
if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) {
ptr = _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, field);
ptr = _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, subs, field);
} else {
ptr = _upb_Decoder_DecodeSubMessage(d, ptr, submsg, field, val->size);
ptr = _upb_Decoder_DecodeSubMessage(d, ptr, submsg, subs, field,
val->size);
}

@@ -641,7 +756,6 @@ break;

case kUpb_DecodeOp_String:
return _upb_Decoder_ReadString2(d, ptr, val->size, mem,
/*validate_utf8=*/true);
_upb_Decoder_VerifyUtf8(d, ptr, val->size);
/* Fallthrough. */
case kUpb_DecodeOp_Bytes:
return _upb_Decoder_ReadString2(d, ptr, val->size, mem,
/*validate_utf8=*/false);
return _upb_Decoder_ReadString(d, ptr, val->size, mem);
case kUpb_DecodeOp_Scalar8Byte:

@@ -663,2 +777,27 @@ memcpy(mem, val, 8);

static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
uint32_t tag) {
int field_number = tag >> 3;
int wire_type = tag & 7;
switch (wire_type) {
case kUpb_WireType_Varint: {
uint64_t val;
return _upb_Decoder_DecodeVarint(d, ptr, &val);
}
case kUpb_WireType_64Bit:
return ptr + 8;
case kUpb_WireType_32Bit:
return ptr + 4;
case kUpb_WireType_Delimited: {
uint32_t size;
ptr = upb_Decoder_DecodeSize(d, ptr, &size);
return ptr + size;
}
case kUpb_WireType_StartGroup:
return _upb_Decoder_DecodeUnknownGroup(d, ptr, field_number);
default:
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
}
enum {

@@ -677,18 +816,11 @@ kStartItemTag = ((kUpb_MsgSet_Item << 3) | kUpb_WireType_StartGroup),

if (UPB_UNLIKELY(!ext)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, 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);
}
&ext->ext->UPB_PRIVATE(field), &ext->data.tagged_msg_val);
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);
}
d->extreg, d->options, &d->arena);
if (status != kUpb_DecodeStatus_Ok) _upb_Decoder_ErrorJmp(d, status);
}

@@ -718,3 +850,3 @@

if (!UPB_PRIVATE(_upb_Message_AddUnknownV)(msg, &d->arena, unknown, 3)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}

@@ -746,5 +878,5 @@ }

StateMask state_mask = 0;
while (!upb_EpsCopyInputStream_IsDone(EPS(d), &ptr)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
uint32_t tag;
ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d));
ptr = _upb_Decoder_DecodeTag(d, ptr, &tag);
switch (tag) {

@@ -755,3 +887,3 @@ case kEndItemTag:

uint64_t tmp;
ptr = upb_WireReader_ReadVarint(ptr, &tmp, EPS(d));
ptr = _upb_Decoder_DecodeVarint(d, ptr, &tmp);
if (state_mask & kUpb_HaveId) break; // Ignore dup.

@@ -768,17 +900,13 @@ state_mask |= kUpb_HaveId;

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);
}
const char* data = upb_EpsCopyInputStream_GetInputPtr(&d->input, ptr);
ptr += size;
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);
upb_Decoder_AddMessageSetItem(d, msg, layout, type_id, data, size);
} else {
// Out of order, we must preserve the payload.
preserved = sv;
preserved.data = data;
preserved.size = size;
}

@@ -789,7 +917,7 @@ break;

// We do not preserve unexpected fields inside a message set item.
ptr = _upb_WireReader_SkipValue(ptr, tag, d->depth, &d->input);
ptr = upb_Decoder_SkipField(d, ptr, tag);
break;
}
}
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}

@@ -802,3 +930,3 @@

upb_Decoder* d, const upb_MiniTable* t, uint32_t field_number, int ext_mode,
uint32_t wire_type) {
int wire_type) {
// Treat a message set as an extendable message if it is a delimited field.

@@ -826,4 +954,5 @@ // This provides compatibility with encoders that are unaware of message

uint32_t field_number,
uint32_t wire_type) {
UPB_ASSERT(t);
int wire_type) {
if (t == NULL) return &upb_Decoder_FieldNotFoundField;
const upb_MiniTableField* field =

@@ -873,4 +1002,8 @@ upb_MiniTable_FindFieldByNumber(t, field_number);

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.
const upb_MiniTable* mt_sub =
_upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field);
if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) ||
!UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) {
return;
}
#ifndef NDEBUG

@@ -883,3 +1016,5 @@ const upb_MiniTableField* oneof = upb_MiniTable_GetOneof(mt, field);

UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message);
const upb_MiniTable* oneof_sub = upb_MiniTable_GetSubMessageTable(oneof);
const upb_MiniTable* oneof_sub =
*mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(
submsg);
UPB_ASSERT(!oneof_sub);

@@ -895,6 +1030,5 @@ } while (upb_MiniTable_NextOneofField(mt, &oneof));

const upb_MiniTableField* field, int* op) {
UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes);
if (_upb_Decoder_FieldRequiresUtf8Validation(d, field)) {
if ((field->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) &&
UPB_UNLIKELY(d->options & kUpb_DecodeOption_AlwaysValidateUtf8))
*op = kUpb_DecodeOp_String;
}
}

@@ -969,4 +1103,3 @@

const upb_MiniTableField* field,
uint32_t wire_type, wireval* val,
int* op) {
int wire_type, wireval* val, int* op) {
static const unsigned kFixed32OkMask = (1 << kUpb_FieldType_Float) |

@@ -982,5 +1115,9 @@ (1 << kUpb_FieldType_Fixed32) |

case kUpb_WireType_Varint:
ptr = upb_WireReader_ReadVarint(ptr, &val->uint64_val, EPS(d));
ptr = _upb_Decoder_DecodeVarint(d, ptr, &val->uint64_val);
if (upb_MiniTableField_IsClosedEnum(field)) {
const upb_MiniTableEnum* e = upb_MiniTable_GetSubEnumTable(field);
const upb_MiniTableEnum* e =
upb_MiniTableField_IsExtension(field)
? upb_MiniTableExtension_GetSubEnum(
(const upb_MiniTableExtension*)field)
: upb_MiniTable_GetSubEnumTable(mt, field);
if (!upb_MiniTableEnum_CheckValue(e, val->uint64_val)) {

@@ -1026,3 +1163,3 @@ *op = kUpb_DecodeOp_UnknownField;

}
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}

@@ -1036,3 +1173,5 @@

int op, wireval* val) {
const upb_MiniTableSubInternal* subs = layout->UPB_PRIVATE(subs);
uint8_t mode = field->UPB_PRIVATE(mode);
upb_MiniTableSubInternal ext_sub;

@@ -1045,6 +1184,14 @@ if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {

if (UPB_UNLIKELY(!ext)) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
d->original_msg = msg;
msg = &ext->data.UPB_PRIVATE(ext_msg_val);
if (upb_MiniTableField_IsSubMessage(&ext->ext->UPB_PRIVATE(field))) {
ext_sub.UPB_PRIVATE(submsg) =
&ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg);
} else {
ext_sub.UPB_PRIVATE(subenum) =
ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum);
}
subs = &ext_sub;
}

@@ -1054,7 +1201,7 @@

case kUpb_FieldMode_Array:
return _upb_Decoder_DecodeToArray(d, ptr, msg, field, val, op);
return _upb_Decoder_DecodeToArray(d, ptr, msg, subs, field, val, op);
case kUpb_FieldMode_Map:
return _upb_Decoder_DecodeToMap(d, ptr, msg, field, val);
return _upb_Decoder_DecodeToMap(d, ptr, msg, subs, field, val);
case kUpb_FieldMode_Scalar:
return _upb_Decoder_DecodeToSubMessage(d, ptr, msg, field, val, op);
return _upb_Decoder_DecodeToSubMessage(d, ptr, msg, subs, field, val, op);
default:

@@ -1065,5 +1212,9 @@ UPB_UNREACHABLE();

static const char* _upb_Decoder_FindFieldStart(upb_Decoder* d, const char* ptr,
uint32_t field_number,
uint32_t wire_type) {
static const char* _upb_Decoder_DecodeUnknownField(upb_Decoder* d,
const char* ptr,
upb_Message* msg,
int field_number,
int wire_type, wireval val) {
if (field_number == 0) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
// Since unknown fields are the uncommon case, we do a little extra work here

@@ -1076,84 +1227,62 @@ // to walk backwards through the buffer to find the field start. This frees

switch (wire_type) {
case kUpb_WireType_Varint:
case kUpb_WireType_Delimited:
// Skip the last byte
start--;
// Skip bytes until we encounter the final byte of the tag varint.
while (start[-1] & 0x80) start--;
break;
case kUpb_WireType_32Bit:
start -= 4;
break;
case kUpb_WireType_64Bit:
start -= 8;
break;
default:
break;
}
assert(start == d->debug_valstart);
if (wire_type == kUpb_WireType_Delimited) ptr += val.size;
if (msg) {
switch (wire_type) {
case kUpb_WireType_Varint:
case kUpb_WireType_Delimited:
// Skip the last byte
start--;
// Skip bytes until we encounter the final byte of the tag varint.
while (start[-1] & 0x80) start--;
break;
case kUpb_WireType_32Bit:
start -= 4;
break;
case kUpb_WireType_64Bit:
start -= 8;
break;
default:
break;
}
{
// The varint parser does not enforce that integers are encoded with their
// minimum size; for example the value 1 could be encoded with three
// bytes: 0x81, 0x80, 0x00. These unnecessary trailing zeroes mean that we
// cannot skip backwards by the minimum encoded size of the tag; and
// unlike the loop for delimited or varint fields, we can't stop at a
// sentinel value because anything can precede a tag. Instead, parse back
// one byte at a time until we read the same tag value that was parsed
// earlier.
uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
uint32_t seen = 0;
do {
start--;
seen <<= 7;
seen |= *start & 0x7f;
} while (seen != tag);
}
assert(start == d->debug_tagstart);
assert(start == d->debug_valstart);
{
// The varint parser does not enforce that integers are encoded with their
// minimum size; for example the value 1 could be encoded with three
// bytes: 0x81, 0x80, 0x00. These unnecessary trailing zeroes mean that we
// cannot skip backwards by the minimum encoded size of the tag; and
// unlike the loop for delimited or varint fields, we can't stop at a
// sentinel value because anything can precede a tag. Instead, parse back
// one byte at a time until we read the same tag value that was parsed
// earlier.
uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
uint32_t seen = 0;
do {
start--;
seen <<= 7;
seen |= *start & 0x7f;
} while (seen != tag);
}
assert(start == d->debug_tagstart);
return start;
}
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) {
if (field_number == 0) {
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
}
const char* start =
_upb_Decoder_FindFieldStart(d, ptr, field_number, wire_type);
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);
const char* input_start =
upb_EpsCopyInputStream_GetInputPtr(&d->input, start);
if (wire_type == kUpb_WireType_StartGroup) {
ptr = _upb_Decoder_DecodeUnknownGroup(d, ptr, field_number);
}
// Normally, bounds checks for fixed or varint fields are performed after
// the field is parsed; it's OK for the field to overrun the end of the
// buffer, because it'll just read into slop space. However, because this
// path reads bytes from the input buffer rather than the patch buffer,
// bounds checks are needed before adding the unknown field.
_upb_Decoder_IsDone(d, &ptr);
const char* input_ptr = upb_EpsCopyInputStream_GetInputPtr(&d->input, ptr);
if (!UPB_PRIVATE(_upb_Message_AddUnknown)(
msg, input_start, input_ptr - input_start, &d->arena,
d->input.aliasing ? d->input.buffer_start : NULL)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
} else if (wire_type == kUpb_WireType_StartGroup) {
ptr = UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, field_number << 3,
d->depth, &d->input);
ptr = _upb_Decoder_DecodeUnknownGroup(d, ptr, field_number);
}
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;

@@ -1164,4 +1293,3 @@ }

const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr,
uint32_t* field_number,
uint32_t* wire_type) {
int* field_number, int* wire_type) {
#ifndef NDEBUG

@@ -1173,3 +1301,3 @@ d->debug_tagstart = ptr;

UPB_ASSERT(ptr < d->input.limit_ptr);
ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d));
ptr = _upb_Decoder_DecodeTag(d, ptr, &tag);
*field_number = tag >> 3;

@@ -1184,4 +1312,3 @@ *wire_type = tag & 7;

const upb_MiniTable* mt,
uint32_t field_number,
uint32_t wire_type) {
int field_number, int wire_type) {
#ifndef NDEBUG

@@ -1222,4 +1349,4 @@ d->debug_valstart = ptr;

const upb_MiniTable* mt) {
uint32_t field_number;
uint32_t wire_type;
int field_number;
int wire_type;

@@ -1239,49 +1366,20 @@ ptr = _upb_Decoder_DecodeFieldTag(d, ptr, &field_number, &wire_type);

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)) {
#ifdef UPB_ENABLE_FASTTABLE
if (mt && mt->UPB_PRIVATE(table_mask) != (unsigned char)-1 &&
!(d->options & kUpb_DecodeOption_DisableFastTable)) {
intptr_t table = decode_totable(mt);
ptr = upb_DecodeFast_Dispatch(d, ptr, msg, table, 0, 0);
if (d->message_is_done) return ptr;
_upb_Decoder_Trace(d, '<');
} else if (_upb_Decoder_IsDone(d, &ptr)) {
return _upb_Decoder_EndMessage(d, ptr);
}
#else
if (_upb_Decoder_IsDone(d, &ptr)) {
return _upb_Decoder_EndMessage(d, ptr);
}
#endif

@@ -1295,3 +1393,2 @@ return _upb_Decoder_DecodeFieldNoFast(d, ptr, msg, mt);

const upb_MiniTable* mt) {
UPB_ASSERT(mt);
UPB_ASSERT(d->message_is_done == false);

@@ -1324,6 +1421,6 @@

upb_Arena* const arena) {
if (UPB_SETJMP(decoder->err.buf) == 0) {
decoder->err.code = _upb_Decoder_DecodeTop(decoder, buf, msg, m);
if (UPB_SETJMP(decoder->err) == 0) {
decoder->status = _upb_Decoder_DecodeTop(decoder, buf, msg, m);
} else {
UPB_ASSERT(decoder->err.code != kUpb_DecodeStatus_Ok);
UPB_ASSERT(decoder->status != kUpb_DecodeStatus_Ok);
}

@@ -1416,2 +1513,4 @@

return "Missing required field";
case kUpb_DecodeStatus_UnlinkedSubMessage:
return "Unlinked sub-message field was present";
default:

@@ -1418,0 +1517,0 @@ return "Unknown decode status";

@@ -55,2 +55,37 @@ // Protocol Buffers - Google's data interchange format

*
* If set, the parser will allow parsing of sub-message fields that were not
* previously linked using upb_MiniTable_SetSubMessage(). The data will be
* parsed into an internal "empty" message type that cannot be accessed
* directly, but can be later promoted into the true message type if the
* sub-message fields are linked at a later time.
*
* Users should set this option if they intend to perform dynamic tree shaking
* and promoting using the interfaces in message/promote.h. If this option is
* enabled, it is important that the resulting messages are only accessed by
* code that is aware of promotion rules:
*
* 1. Message pointers in upb_Message, upb_Array, and upb_Map are represented
* by a tagged pointer upb_TaggedMessagePointer. The tag indicates whether
* the message uses the internal "empty" type.
*
* 2. Any code *reading* these message pointers must test whether the "empty"
* tag bit is set, using the interfaces in mini_table/types.h. However
* writing of message pointers should always use plain upb_Message*, since
* users are not allowed to create "empty" messages.
*
* 3. It is always safe to test whether a field is present or test the array
* length; these interfaces will reflect that empty messages are present,
* even though their data cannot be accessed without promoting first.
*
* 4. If a message pointer is indeed tagged as empty, the message may not be
* accessed directly, only promoted through the interfaces in
* message/promote.h.
*
* 5. Tagged/empty messages may never be created by the user. They may only
* be created by the parser or the message-copying logic in message/copy.h.
*/
kUpb_DecodeOption_ExperimentalAllowUnlinked = 4,
/* EXPERIMENTAL:
*
* If set, decoding will enforce UTF-8 validation for string fields, even for

@@ -87,4 +122,4 @@ * proto2 or fields with `features.utf8_validation = NONE`. Normally, only

kUpb_DecodeStatus_Ok = 0,
kUpb_DecodeStatus_OutOfMemory = 1, // Arena alloc failed
kUpb_DecodeStatus_Malformed = 2, // Wire format was corrupt
kUpb_DecodeStatus_Malformed = 1, // Wire format was corrupt
kUpb_DecodeStatus_OutOfMemory = 2, // Arena alloc failed
kUpb_DecodeStatus_BadUtf8 = 3, // String field had bad UTF-8

@@ -97,4 +132,9 @@ kUpb_DecodeStatus_MaxDepthExceeded =

kUpb_DecodeStatus_MissingRequired = 5,
// Unlinked sub-message field was present, but
// kUpb_DecodeOptions_ExperimentalAllowUnlinked was not specified in the list
// of options.
kUpb_DecodeStatus_UnlinkedSubMessage = 6,
} upb_DecodeStatus;
// LINT.ThenChange(//depot/google3/third_party/upb/rust/sys/wire/wire.rs:decode_status)
// LINT.ThenChange(//depot/google3/third_party/protobuf/rust/upb.rs:decode_status)

@@ -101,0 +141,0 @@ UPB_API upb_DecodeStatus upb_Decode(const char* buf, size_t size,

@@ -33,4 +33,6 @@ // Protocol Buffers - Google's data interchange format

#include "upb/message/internal/message.h"
#include "upb/message/internal/tagged_ptr.h"
#include "upb/message/map.h"
#include "upb/message/message.h"
#include "upb/message/tagged_ptr.h"
#include "upb/mini_table/extension.h"

@@ -49,2 +51,9 @@ #include "upb/mini_table/field.h"

// Returns the MiniTable corresponding to a given MiniTableField
// from an array of MiniTableSubs.
static const upb_MiniTable* _upb_Encoder_GetSubMiniTable(
const upb_MiniTableSubInternal* subs, const upb_MiniTableField* field) {
return *subs[field->UPB_PRIVATE(submsg_index)].UPB_PRIVATE(submsg);
}
static uint32_t encode_zz32(int32_t n) {

@@ -83,14 +92,9 @@ return ((uint32_t)n << 1) ^ (n >> 31);

// 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) {
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);
size_t new_size = upb_roundup_pow2(needed_size);
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);
char* new_buf =
upb_Arena_Realloc(e->arena, (void*)e->buf, old_size, new_size);

@@ -122,10 +126,2 @@ if (!new_buf) encode_err(e, kUpb_EncodeStatus_OutOfMemory);

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. */

@@ -140,16 +136,13 @@ static char* encode_bytes(char* ptr, upb_encstate* e, const void* data,

static char* encode_fixed64_unchecked(char* ptr, upb_encstate* e,
uint64_t val) {
static char* encode_fixed64(char* ptr, upb_encstate* e, uint64_t val) {
val = upb_BigEndian64(val);
return encode_bytes_unchecked(ptr, e, &val, sizeof(uint64_t));
return encode_bytes(ptr, e, &val, sizeof(uint64_t));
}
static char* encode_fixed32_unchecked(char* ptr, upb_encstate* e,
uint32_t val) {
static char* encode_fixed32(char* ptr, upb_encstate* e, uint32_t val) {
val = upb_BigEndian32(val);
return encode_bytes_unchecked(ptr, e, &val, sizeof(uint32_t));
return encode_bytes(ptr, e, &val, sizeof(uint32_t));
}
#define UPB_PB_VARINT_MAX_LEN 10
#define UPB_PB_VARINT32_MAX_LEN 5

@@ -193,7 +186,3 @@ #if UPB_ARM64_ASM

"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"

@@ -255,6 +244,4 @@ // We don't need addr any more, but we've got the register for our whole

: "memory");
// Encode the final byte after the continuation bytes.
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);

@@ -284,12 +271,2 @@ return ptr;

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) {

@@ -305,51 +282,16 @@ if (val < 128 && ptr != e->buf) {

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) {
static char* encode_double(char* ptr, upb_encstate* e, double d) {
uint64_t u64;
UPB_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t), "bad double size");
UPB_ASSERT(sizeof(double) == sizeof(uint64_t));
memcpy(&u64, &d, sizeof(uint64_t));
return encode_fixed64_unchecked(ptr, e, u64);
return encode_fixed64(ptr, e, u64);
}
static char* encode_float_unchecked(char* ptr, upb_encstate* e, float d) {
static char* encode_float(char* ptr, upb_encstate* e, float d) {
uint32_t u32;
UPB_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t), "bad float size");
UPB_ASSERT(sizeof(float) == sizeof(uint32_t));
memcpy(&u32, &d, sizeof(uint32_t));
return encode_fixed32_unchecked(ptr, e, u32);
return encode_fixed32(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,

@@ -396,13 +338,24 @@ uint8_t wire_type) {

static char* encode_scalar(char* ptr, upb_encstate* e, const void* field_mem,
static char* encode_TaggedMessagePtr(char* ptr, upb_encstate* e,
upb_TaggedMessagePtr tagged,
const upb_MiniTable* m, size_t* size) {
if (upb_TaggedMessagePtr_IsEmpty(tagged)) {
m = UPB_PRIVATE(_upb_MiniTable_Empty)();
}
return encode_message(
ptr, e, UPB_PRIVATE(_upb_TaggedMessagePtr_GetMessage)(tagged), m, size);
}
static char* encode_scalar(char* ptr, upb_encstate* e, const void* _field_mem,
const upb_MiniTableSubInternal* subs,
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); \
const char* field_mem = _field_mem;
int wire_type;
#define CASE(ctype, type, wtype, encodeval) \
{ \
ctype val = *(ctype*)field_mem; \
ptr = encode_##type(ptr, e, encodeval); \
wire_type = wtype; \
break; \
}

@@ -438,15 +391,11 @@

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);
ptr = encode_bytes(ptr, e, view.data, view.size);
ptr = encode_varint(ptr, e, view.size);
wire_type = kUpb_WireType_Delimited;
break;
}
case kUpb_FieldType_Group: {
size_t size;
upb_Message* submsg = *(upb_Message**)field_mem;
const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f);
upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem;
const upb_MiniTable* subm = _upb_Encoder_GetSubMiniTable(subs, f);
if (submsg == 0) {

@@ -458,11 +407,11 @@ return ptr;

kUpb_WireType_EndGroup);
ptr = encode_message(ptr, e, submsg, subm, &size);
ptr = encode_TaggedMessagePtr(ptr, e, submsg, subm, &size);
wire_type = kUpb_WireType_StartGroup;
e->depth++;
return encode_tag(ptr, e, upb_MiniTableField_Number(f),
kUpb_WireType_StartGroup);
break;
}
case kUpb_FieldType_Message: {
size_t size;
upb_Message* submsg = *(upb_Message**)field_mem;
const upb_MiniTable* subm = upb_MiniTable_GetSubMessageTable(f);
upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem;
const upb_MiniTable* subm = _upb_Encoder_GetSubMiniTable(subs, f);
if (submsg == 0) {

@@ -472,10 +421,7 @@ return ptr;

if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);
ptr = encode_message(ptr, e, submsg, subm, &size);
ptr = encode_TaggedMessagePtr(ptr, e, submsg, subm, &size);
ptr = encode_varint(ptr, e, size);
wire_type = kUpb_WireType_Delimited;
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);
break;
}

@@ -486,5 +432,8 @@ default:

#undef CASE
return encode_tag(ptr, e, upb_MiniTableField_Number(f), wire_type);
}
static char* encode_array(char* ptr, upb_encstate* e, const upb_Message* msg,
const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* f) {

@@ -557,3 +506,3 @@ const upb_Array* arr = *UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), upb_Array*);

ptr = encode_bytes(ptr, e, str_ptr->data, str_ptr->size);
ptr = encode_length(ptr, e, str_ptr->size);
ptr = encode_varint(ptr, e, str_ptr->size);
ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f),

@@ -565,5 +514,5 @@ kUpb_WireType_Delimited);

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);
const upb_TaggedMessagePtr* start = upb_Array_DataPtr(arr);
const upb_TaggedMessagePtr* arr_ptr = start + upb_Array_Size(arr);
const upb_MiniTable* subm = _upb_Encoder_GetSubMiniTable(subs, f);
if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);

@@ -575,3 +524,3 @@ do {

kUpb_WireType_EndGroup);
ptr = encode_message(ptr, e, *arr_ptr, subm, &size);
ptr = encode_TaggedMessagePtr(ptr, e, *arr_ptr, subm, &size);
ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f),

@@ -584,5 +533,5 @@ kUpb_WireType_StartGroup);

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);
const upb_TaggedMessagePtr* start = upb_Array_DataPtr(arr);
const upb_TaggedMessagePtr* arr_ptr = start + upb_Array_Size(arr);
const upb_MiniTable* subm = _upb_Encoder_GetSubMiniTable(subs, f);
if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);

@@ -592,4 +541,4 @@ do {

arr_ptr--;
ptr = encode_message(ptr, e, *arr_ptr, subm, &size);
ptr = encode_length(ptr, e, size);
ptr = encode_TaggedMessagePtr(ptr, e, *arr_ptr, subm, &size);
ptr = encode_varint(ptr, e, size);
ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f),

@@ -605,3 +554,3 @@ kUpb_WireType_Delimited);

if (packed) {
ptr = encode_length(ptr, e, e->limit - ptr - pre_len);
ptr = encode_varint(ptr, e, e->limit - ptr - pre_len);
ptr = encode_tag(ptr, e, upb_MiniTableField_Number(f),

@@ -620,6 +569,6 @@ kUpb_WireType_Delimited);

size_t size;
ptr = encode_scalar(ptr, e, &ent->v, val_field);
ptr = encode_scalar(ptr, e, &ent->k, key_field);
ptr = encode_scalar(ptr, e, &ent->v, layout->UPB_PRIVATE(subs), val_field);
ptr = encode_scalar(ptr, e, &ent->k, layout->UPB_PRIVATE(subs), key_field);
size = (e->limit - ptr) - pre_len;
ptr = encode_length(ptr, e, size);
ptr = encode_varint(ptr, e, size);
ptr = encode_tag(ptr, e, number, kUpb_WireType_Delimited);

@@ -630,5 +579,6 @@ return ptr;

static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg,
const upb_MiniTableSubInternal* subs,
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);
const upb_MiniTable* layout = _upb_Encoder_GetSubMiniTable(subs, f);
UPB_ASSERT(upb_MiniTable_FieldCount(layout) == 2);

@@ -728,11 +678,13 @@

static char* encode_field(char* ptr, upb_encstate* e, const upb_Message* msg,
const upb_MiniTableSubInternal* subs,
const upb_MiniTableField* field) {
switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) {
case kUpb_FieldMode_Array:
return encode_array(ptr, e, msg, field);
return encode_array(ptr, e, msg, subs, field);
case kUpb_FieldMode_Map:
return encode_map(ptr, e, msg, field);
return encode_map(ptr, e, msg, subs, field);
case kUpb_FieldMode_Scalar:
return encode_scalar(
ptr, e, UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void), field);
return encode_scalar(ptr, e,
UPB_PTR_AT(msg, field->UPB_PRIVATE(offset), void),
subs, field);
default:

@@ -764,3 +716,9 @@ UPB_UNREACHABLE();

} else {
ptr = encode_field(ptr, e, &ext_val.UPB_PRIVATE(ext_msg_val),
upb_MiniTableSubInternal sub;
if (upb_MiniTableField_IsSubMessage(&ext->UPB_PRIVATE(field))) {
sub.UPB_PRIVATE(submsg) = &ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg);
} else {
sub.UPB_PRIVATE(subenum) = ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum);
}
ptr = encode_field(ptr, e, &ext_val.UPB_PRIVATE(ext_msg_val), &sub,
&ext->UPB_PRIVATE(field));

@@ -852,3 +810,3 @@ }

if (encode_shouldencode(msg, f)) {
ptr = encode_field(ptr, e, msg, f);
ptr = encode_field(ptr, e, msg, m->UPB_PRIVATE(subs), f);
}

@@ -876,3 +834,3 @@ }

if (prepend_len) {
ptr = encode_length(ptr, encoder, encoded_msg_size);
ptr = encode_varint(ptr, encoder, encoded_msg_size);
}

@@ -914,4 +872,4 @@ *size = encoder->limit - ptr;

e.arena = arena;
e.buf = &initial_buf_sentinel;
e.limit = &initial_buf_sentinel;
e.buf = NULL;
e.limit = NULL;
e.depth = upb_EncodeOptions_GetEffectiveMaxDepth(options);

@@ -921,4 +879,3 @@ e.options = options;

return upb_Encoder_Encode(&initial_buf_sentinel, &e, msg, l, buf, size,
prepend_len);
return upb_Encoder_Encode(NULL, &e, msg, l, buf, size, prepend_len);
}

@@ -925,0 +882,0 @@

@@ -52,7 +52,4 @@ // Protocol Buffers - Google's data interchange format

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)
// LINT.ThenChange(//depot/google3/third_party/protobuf/rust/upb.rs:encode_status)

@@ -59,0 +56,0 @@ UPB_INLINE uint32_t upb_EncodeOptions_MaxDepth(uint16_t depth) {

@@ -10,40 +10,11 @@ // Protocol Buffers - Google's data interchange format

#include <stdint.h>
#include <string.h>
#include "upb/base/error_handler.h"
#include "upb/wire/internal/eps_copy_input_stream.h"
// Must be last.
#include "upb/port/def.inc"
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;
static const char* _upb_EpsCopyInputStream_NoOpCallback(
upb_EpsCopyInputStream* e, const char* old_end, const char* new_start) {
return new_start;
}
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);
}
const char* _upb_EpsCopyInputStream_IsDoneFallbackNoCallback(
upb_EpsCopyInputStream* e, const char* ptr, int overrun) {
return _upb_EpsCopyInputStream_IsDoneFallbackInline(
e, ptr, overrun, _upb_EpsCopyInputStream_NoOpCallback);
}

@@ -11,8 +11,6 @@ // Protocol Buffers - Google's data interchange format

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "upb/base/error_handler.h"
#include "upb/base/string_view.h"
#include "upb/wire/internal/eps_copy_input_stream.h"
#include "upb/mem/arena.h"

@@ -26,4 +24,68 @@ // Must be last.

typedef struct upb_EpsCopyInputStream upb_EpsCopyInputStream;
// 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
typedef struct {
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
int limit; // Submessage limit relative to end
bool error; // To distinguish between EOF and error.
bool aliasing;
#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_EpsCopyInputStream;
// 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) {
return e->error;
}
typedef const char* upb_EpsCopyInputStream_BufferFlipCallback(
upb_EpsCopyInputStream* e, const char* old_end, const char* new_start);
typedef const char* upb_EpsCopyInputStream_IsDoneFallbackFunc(
upb_EpsCopyInputStream* e, const char* ptr, int overrun);
UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(
upb_EpsCopyInputStream* e) {
#ifndef NDEBUG
e->guaranteed_bytes = kUpb_EpsCopyInputStream_SlopBytes;
#endif
}
UPB_INLINE void UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(
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)(
upb_EpsCopyInputStream* e, int n) {
#ifndef NDEBUG
if (e) {
UPB_ASSERT(e->guaranteed_bytes >= n);
e->guaranteed_bytes -= n;
}
#endif
}
// Initializes a upb_EpsCopyInputStream using the contents of the buffer

@@ -33,27 +95,52 @@ // [*ptr, size]. Updates `*ptr` as necessary to guarantee that at least

UPB_INLINE void upb_EpsCopyInputStream_Init(upb_EpsCopyInputStream* e,
const char** ptr, size_t size);
const char** ptr, size_t size,
bool enable_aliasing) {
e->buffer_start = *ptr;
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->aliasing = enable_aliasing;
e->limit_ptr = e->end;
e->error = false;
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e);
}
// 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);
typedef enum {
// The current stream position is at a limit.
kUpb_IsDoneStatus_Done,
// 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);
// The current stream position is not at a limit.
kUpb_IsDoneStatus_NotDone,
// 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);
// 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_EpsCopyInputStream_IsDoneStatus(
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;
}
}
// Returns true if the stream has hit a limit, either the current delimited

@@ -66,2 +153,31 @@ // limit or the overall end-of-stream. As a side effect, this function may flip

// kUpb_EpsCopyInputStream_SlopBytes of data available to read at *ptr.
UPB_INLINE bool upb_EpsCopyInputStream_IsDoneWithCallback(
upb_EpsCopyInputStream* e, const char** ptr,
upb_EpsCopyInputStream_IsDoneFallbackFunc* func) {
int overrun;
switch (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 = func(e, *ptr, overrun);
if (*ptr) {
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e);
} else {
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsHit)(e);
}
return *ptr == NULL;
}
UPB_UNREACHABLE();
}
const char* _upb_EpsCopyInputStream_IsDoneFallbackNoCallback(
upb_EpsCopyInputStream* e, const char* ptr, int overrun);
// A simpler version of IsDoneWithCallback() that does not support a buffer flip
// callback. Useful in cases where we do not need to insert custom logic at
// every buffer flip.
//

@@ -71,4 +187,20 @@ // If this returns true, the user must call upb_EpsCopyInputStream_IsError()

UPB_INLINE bool upb_EpsCopyInputStream_IsDone(upb_EpsCopyInputStream* e,
const char** ptr);
const char** ptr) {
return upb_EpsCopyInputStream_IsDoneWithCallback(
e, ptr, _upb_EpsCopyInputStream_IsDoneFallbackNoCallback);
}
// Returns the total number of bytes that are safe to read from the current
// buffer without reading uninitialized or unallocated memory.
//
// Note that this check does not respect any semantic limits on the stream,
// either limits from PushLimit() or the overall stream end, so some of these
// bytes may have unpredictable, nonsense values in them. The guarantee is only
// that the bytes are valid to read from the perspective of the C language
// (ie. you can read without triggering UBSAN or ASAN).
UPB_INLINE size_t upb_EpsCopyInputStream_BytesAvailable(
upb_EpsCopyInputStream* e, const char* ptr) {
return (e->end - ptr) + kUpb_EpsCopyInputStream_SlopBytes;
}
// Returns true if the given delimited field size is valid (it does not extend

@@ -81,55 +213,160 @@ // beyond any previously-pushed limits). `ptr` should point to the beginning

UPB_INLINE bool upb_EpsCopyInputStream_CheckSize(
const upb_EpsCopyInputStream* e, const char* ptr, int size);
const upb_EpsCopyInputStream* e, const char* ptr, int size) {
UPB_ASSERT(size >= 0);
return size <= e->limit - (ptr - e->end);
}
// 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);
UPB_INLINE bool _upb_EpsCopyInputStream_CheckSizeAvailable(
upb_EpsCopyInputStream* e, const char* ptr, int size, bool submessage) {
// This is one extra branch compared to the more normal:
// return (size_t)(end - ptr) < size;
// However it is one less computation if we are just about to use "ptr + len":
// https://godbolt.org/z/35YGPz
// In microbenchmarks this shows a small improvement.
uintptr_t uptr = (uintptr_t)ptr;
uintptr_t uend = (uintptr_t)e->limit_ptr;
uintptr_t res = uptr + (size_t)size;
if (!submessage) uend += kUpb_EpsCopyInputStream_SlopBytes;
// NOTE: this check depends on having a linear address space. This is not
// technically guaranteed by uintptr_t.
bool ret = res >= uptr && res <= uend;
if (size < 0) UPB_ASSERT(!ret);
return ret;
}
// 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);
// Returns true if the given delimited field size is valid (it does not extend
// beyond any previously-pushed limited) *and* all of the data for this field is
// available to be read in the current buffer.
//
// If the size is negative, this function will always return false. This
// property can be useful in some cases.
UPB_INLINE bool upb_EpsCopyInputStream_CheckDataSizeAvailable(
upb_EpsCopyInputStream* e, const char* ptr, int size) {
return _upb_EpsCopyInputStream_CheckSizeAvailable(e, ptr, size, false);
}
// Reads a string from the stream and advances the pointer accordingly. The
// returned string view will always alias the input buffer.
// Returns true if the given sub-message size is valid (it does not extend
// beyond any previously-pushed limited) *and* all of the data for this
// sub-message is available to be parsed in the current 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.
// This implies that all fields from the sub-message can be parsed from the
// current buffer while maintaining the invariant that we always have at least
// kUpb_EpsCopyInputStream_SlopBytes of data available past the beginning of
// any individual field start.
//
// 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);
// If the size is negative, this function will always return false. This
// property can be useful in some cases.
UPB_INLINE bool upb_EpsCopyInputStream_CheckSubMessageSizeAvailable(
upb_EpsCopyInputStream* e, const char* ptr, int size) {
return _upb_EpsCopyInputStream_CheckSizeAvailable(e, ptr, size, true);
}
// 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 true if aliasing_enabled=true was passed to
// upb_EpsCopyInputStream_Init() when this stream was initialized.
UPB_INLINE bool upb_EpsCopyInputStream_AliasingEnabled(
upb_EpsCopyInputStream* e) {
return e->aliasing;
}
// Returns true if aliasing_enabled=true was passed to
// upb_EpsCopyInputStream_Init() when this stream was initialized *and* we can
// alias into the region [ptr, size] in an input buffer.
UPB_INLINE bool upb_EpsCopyInputStream_AliasingAvailable(
upb_EpsCopyInputStream* e, const char* ptr, size_t size) {
// When EpsCopyInputStream supports streaming, this will need to become a
// runtime check.
return e->aliasing &&
upb_EpsCopyInputStream_CheckDataSizeAvailable(e, ptr, size);
}
// 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_EpsCopyInputStream_GetInputPtr(
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;
}
// 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.
//
// Returns NULL if size extends beyond the end of the current buffer (which may
// be the patch buffer).
// REQUIRES: Aliasing must be available for the given pointer. If the input is a
// flat buffer and aliasing is enabled, then aliasing will always be available.
UPB_INLINE const char* upb_EpsCopyInputStream_GetAliasedPtr(
upb_EpsCopyInputStream* e, const char* ptr) {
UPB_ASSUME(upb_EpsCopyInputStream_AliasingAvailable(e, ptr, 0));
return upb_EpsCopyInputStream_GetInputPtr(e, ptr);
}
// Reads string data from the input, aliasing into the input buffer instead of
// copying. The parsing pointer is passed in `*ptr`, and will be updated if
// necessary to point to the actual input buffer. Returns the new parsing
// pointer, which will be advanced past the string data.
//
// 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.
// REQUIRES: Aliasing must be available for this data region (test with
// upb_EpsCopyInputStream_AliasingAvailable().
UPB_INLINE const char* upb_EpsCopyInputStream_ReadStringAliased(
upb_EpsCopyInputStream* e, const char** ptr, size_t size) {
UPB_ASSUME(upb_EpsCopyInputStream_AliasingAvailable(e, *ptr, size));
const char* ret = *ptr + size;
*ptr = upb_EpsCopyInputStream_GetAliasedPtr(e, *ptr);
UPB_ASSUME(ret != NULL);
return ret;
}
// Skips `size` bytes of data from the input and returns a pointer past the end.
// Returns NULL on end of stream or error.
UPB_INLINE const char* upb_EpsCopyInputStream_Skip(upb_EpsCopyInputStream* e,
const char* ptr, int size) {
if (!upb_EpsCopyInputStream_CheckDataSizeAvailable(e, ptr, size)) return NULL;
return ptr + size;
}
// Copies `size` bytes of data from the input `ptr` into the buffer `to`, and
// returns a pointer past the end. Returns NULL on end of stream or error.
UPB_INLINE const char* upb_EpsCopyInputStream_Copy(upb_EpsCopyInputStream* e,
const char* ptr, void* to,
int size) {
if (!upb_EpsCopyInputStream_CheckDataSizeAvailable(e, ptr, size)) return NULL;
memcpy(to, ptr, size);
return ptr + size;
}
// Reads string data from the stream and advances the pointer accordingly.
// If aliasing was enabled when the stream was initialized, then the returned
// pointer will point into the input buffer if possible, otherwise new data
// will be allocated from arena and copied into. We may be forced to copy even
// if aliasing was enabled if the input data spans input buffers.
//
// 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);
// Returns NULL if memory allocation failed, or we reached a premature EOF.
UPB_INLINE const char* upb_EpsCopyInputStream_ReadString(
upb_EpsCopyInputStream* e, const char** ptr, size_t size,
upb_Arena* arena) {
if (upb_EpsCopyInputStream_AliasingAvailable(e, *ptr, size)) {
return upb_EpsCopyInputStream_ReadStringAliased(e, ptr, size);
} else {
// We need to allocate and copy.
if (!upb_EpsCopyInputStream_CheckDataSizeAvailable(e, *ptr, size)) {
return NULL;
}
UPB_ASSERT(arena);
char* data = (char*)upb_Arena_Malloc(arena, size);
if (!data) return NULL;
const char* ret = upb_EpsCopyInputStream_Copy(e, *ptr, data, size);
*ptr = data;
return ret;
}
}
UPB_INLINE void _upb_EpsCopyInputStream_CheckLimit(upb_EpsCopyInputStream* e) {
UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit));
}
// Pushes a limit onto the stack of limits for the current stream. The limit

@@ -141,9 +378,13 @@ // will extend for `size` bytes beyond the position in `ptr`. Future calls to

// 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);
UPB_INLINE int upb_EpsCopyInputStream_PushLimit(upb_EpsCopyInputStream* e,
const char* ptr, int size) {
int limit = size + (int)(ptr - e->end);
int delta = e->limit - limit;
_upb_EpsCopyInputStream_CheckLimit(e);
UPB_ASSERT(limit <= e->limit);
e->limit = limit;
e->limit_ptr = e->end + UPB_MIN(0, limit);
_upb_EpsCopyInputStream_CheckLimit(e);
return delta;
}

@@ -155,4 +396,42 @@ // Pops the last limit that was pushed on this stream. This may only be called

const char* ptr,
ptrdiff_t saved_delta);
int saved_delta) {
UPB_ASSERT(ptr - e->end == e->limit);
_upb_EpsCopyInputStream_CheckLimit(e);
e->limit += saved_delta;
e->limit_ptr = e->end + UPB_MIN(0, e->limit);
_upb_EpsCopyInputStream_CheckLimit(e);
}
UPB_INLINE const char* _upb_EpsCopyInputStream_IsDoneFallbackInline(
upb_EpsCopyInputStream* e, const char* ptr, int overrun,
upb_EpsCopyInputStream_BufferFlipCallback* callback) {
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[0] + 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;
const char* ret = callback(e, old_end, new_start);
if (ret) {
UPB_PRIVATE(upb_EpsCopyInputStream_BoundsChecked)(e);
}
return ret;
} else {
UPB_ASSERT(overrun > e->limit);
e->error = true;
return callback(e, NULL, NULL);
}
}
typedef const char* upb_EpsCopyInputStream_ParseDelimitedFunc(
upb_EpsCopyInputStream* e, const char* ptr, void* ctx);
// Tries to perform a fast-path handling of the given delimited message data.

@@ -164,5 +443,22 @@ // If the sub-message beginning at `*ptr` and extending for `len` is short and

UPB_FORCEINLINE bool upb_EpsCopyInputStream_TryParseDelimitedFast(
upb_EpsCopyInputStream* e, const char** ptr, size_t size,
upb_EpsCopyInputStream_ParseDelimitedFunc* func, void* ctx);
upb_EpsCopyInputStream* e, const char** ptr, int len,
upb_EpsCopyInputStream_ParseDelimitedFunc* func, void* ctx) {
if (!upb_EpsCopyInputStream_CheckSubMessageSizeAvailable(e, *ptr, len)) {
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 + len;
e->limit = e->limit_ptr - e->end;
UPB_ASSERT(e->limit_ptr == e->end + UPB_MIN(0, e->limit));
*ptr = func(e, *ptr, 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

@@ -172,14 +468,4 @@ } /* extern "C" */

#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
#include "upb/port/undef.inc"
#endif // UPB_WIRE_EPS_COPY_INPUT_STREAM_H_

@@ -26,3 +26,2 @@ // Protocol Buffers - Google's data interchange format

d->missing_required =
d->missing_required ||
!UPB_PRIVATE(_upb_Message_IsInitializedShallow)(msg, m);

@@ -32,1 +31,15 @@ }

}
UPB_NORETURN void* _upb_Decoder_ErrorJmp(upb_Decoder* d,
upb_DecodeStatus status) {
UPB_ASSERT(status != kUpb_DecodeStatus_Ok);
d->status = status;
UPB_LONGJMP(d->err, 1);
}
UPB_NOINLINE
const char* _upb_Decoder_IsDoneFallback(upb_EpsCopyInputStream* e,
const char* ptr, int overrun) {
return _upb_EpsCopyInputStream_IsDoneFallbackInline(
e, ptr, overrun, _upb_Decoder_BufferFlipCallback);
}

@@ -21,11 +21,5 @@ // Protocol Buffers - Google's data interchange format

#include "upb/base/descriptor_constants.h"
#include "upb/base/error_handler.h"
#include "upb/base/string_view.h"
#include "upb/mem/arena.h"
#include "upb/mem/internal/arena.h"
#include "upb/message/message.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"

@@ -55,3 +49,4 @@ #include "upb/mini_table/message.h"

};
upb_ErrorHandler err;
upb_DecodeStatus status;
jmp_buf err;

@@ -61,3 +56,2 @@ #ifndef NDEBUG

const char* debug_valstart;
char* trace_buf;
char* trace_ptr;

@@ -73,19 +67,5 @@ char* trace_end;

char* trace_buf, size_t trace_size) {
upb_ErrorHandler_Init(&d->err);
upb_EpsCopyInputStream_InitWithErrorHandler(&d->input, &buf, size, &d->err);
upb_EpsCopyInputStream_Init(&d->input, &buf, size,
options & kUpb_DecodeOption_AliasString);
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;

@@ -96,5 +76,5 @@ d->depth = upb_DecodeOptions_GetEffectiveMaxDepth(options);

d->missing_required = false;
d->status = kUpb_DecodeStatus_Ok;
d->message_is_done = false;
#ifndef NDEBUG
d->trace_buf = trace_buf;
d->trace_ptr = trace_buf;

@@ -117,31 +97,5 @@ d->trace_end = UPB_PTRADD(trace_buf, trace_size);

UPB_PRIVATE(_upb_Arena_SwapOut)(arena, &d->arena);
return (upb_DecodeStatus)d->err.code;
return d->status;
}
#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.

@@ -157,3 +111,3 @@ // Events:

if (d->trace_ptr == NULL) return;
if (_upb_Decoder_TraceBufferFull(d)) {
if (d->trace_ptr == d->trace_end - 1) {
d->trace_ptr[-1] = 'X'; // Truncated.

@@ -187,2 +141,5 @@ return;

const char* _upb_Decoder_IsDoneFallback(upb_EpsCopyInputStream* e,
const char* ptr, int overrun);
const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,

@@ -192,38 +149,19 @@ upb_Message* msg,

UPB_INLINE bool _upb_Decoder_FieldRequiresUtf8Validation(
const upb_Decoder* d, const upb_MiniTableField* field) {
if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_String) return true;
UPB_INLINE bool _upb_Decoder_IsDone(upb_Decoder* d, const char** ptr) {
return upb_EpsCopyInputStream_IsDoneWithCallback(
&d->input, ptr, &_upb_Decoder_IsDoneFallback);
}
if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes &&
(field->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) &&
(d->options & kUpb_DecodeOption_AlwaysValidateUtf8)) {
return true;
}
UPB_NORETURN void* _upb_Decoder_ErrorJmp(upb_Decoder* d,
upb_DecodeStatus status);
return false;
UPB_INLINE const char* _upb_Decoder_BufferFlipCallback(
upb_EpsCopyInputStream* e, const char* old_end, const char* new_start) {
upb_Decoder* d = (upb_Decoder*)e;
if (!old_end) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
return new_start;
}
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;
}
#include "upb/port/undef.inc"
#endif /* UPB_WIRE_INTERNAL_DECODER_H_ */

@@ -32,12 +32,7 @@ // Protocol Buffers - Google's data interchange format

UPB_PRIVATE(_upb_WireReader_LongVarint)
UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(const char* ptr, uint64_t val,
upb_EpsCopyInputStream* stream);
UPB_PRIVATE(_upb_WireReader_ReadLongVarint32)(const char* ptr, uint32_t val);
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_PRIVATE(_upb_WireReader_ReadLongVarint64)(const char* ptr, uint64_t val);
UPB_FORCEINLINE const char* upb_WireReader_ReadVarint(
UPB_FORCEINLINE const char* UPB_PRIVATE(_upb_WireReader_ReadVarint)(
const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream) {

@@ -50,9 +45,10 @@ UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 10);

}
UPB_PRIVATE(_upb_WireReader_LongVarint) res;
res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(ptr, byte, stream);
UPB_PRIVATE(_upb_WireReader_LongVarint)
res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint64)(ptr, byte);
if (UPB_UNLIKELY(!res.ptr)) return NULL;
*val = res.val;
return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr);
return res.ptr;
}
UPB_FORCEINLINE const char* upb_WireReader_ReadTag(
UPB_FORCEINLINE const char* UPB_PRIVATE(_upb_WireReader_ReadTag)(
const char* ptr, uint32_t* val, upb_EpsCopyInputStream* stream) {

@@ -65,22 +61,9 @@ UPB_PRIVATE(upb_EpsCopyInputStream_ConsumeBytes)(stream, 5);

}
UPB_PRIVATE(_upb_WireReader_LongVarint) res;
res = UPB_PRIVATE(_upb_WireReader_ReadLongTag)(ptr, byte, stream);
UPB_PRIVATE(_upb_WireReader_LongVarint)
res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint32)(ptr, byte);
if (UPB_UNLIKELY(!res.ptr)) return NULL;
*val = res.val;
return UPB_PRIVATE(upb_EpsCopyInputStream_AssumeResult)(stream, res.ptr);
return 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) {

@@ -87,0 +70,0 @@ return tag >> kUpb_WireReader_WireTypeBits;

@@ -20,51 +20,39 @@ // Protocol Buffers - Google's data interchange format

UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint)
UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(
const char* ptr, uint64_t val, upb_EpsCopyInputStream* stream) {
UPB_PRIVATE(_upb_WireReader_ReadLongVarint64)(const char* ptr,
uint64_t val) {
UPB_PRIVATE(_upb_WireReader_LongVarint) ret = {NULL, 0};
uint64_t byte;
for (int i = 1; i < 10; i++) {
uint64_t byte = (uint8_t)ptr[i];
byte = (uint8_t)ptr[i];
val += (byte - 1) << (i * 7);
if (!(byte & 0x80)) {
return (UPB_PRIVATE(_upb_WireReader_LongVarint)){ptr + i + 1, val};
ret.ptr = ptr + i + 1;
ret.val = val;
return ret;
}
}
return (UPB_PRIVATE(_upb_WireReader_LongVarint)){
UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0};
return ret;
}
UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint)
UPB_PRIVATE(_upb_WireReader_ReadLongTag)(const char* ptr, uint64_t val,
upb_EpsCopyInputStream* stream) {
UPB_PRIVATE(_upb_WireReader_ReadLongVarint32)(const char* ptr,
uint32_t val) {
UPB_PRIVATE(_upb_WireReader_LongVarint) ret = {NULL, 0};
uint64_t byte;
for (int i = 1; i < 5; i++) {
uint64_t byte = (uint8_t)ptr[i];
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};
ret.ptr = ptr + i + 1;
ret.val = val;
return ret;
}
}
return (UPB_PRIVATE(_upb_WireReader_LongVarint)){
UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream), 0};
return ret;
}
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);
}
if (--depth_limit == 0) return NULL;
uint32_t end_group_tag = (tag & ~7ULL) | kUpb_WireType_EndGroup;

@@ -74,9 +62,8 @@ while (!upb_EpsCopyInputStream_IsDone(stream, &ptr)) {

ptr = upb_WireReader_ReadTag(ptr, &tag, stream);
if (!ptr) break;
if (!ptr) return NULL;
if (tag == end_group_tag) return ptr;
ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, stream);
if (!ptr) break;
if (!ptr) return NULL;
}
// Encountered limit end before end group tag.
return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream);
return ptr;
}

@@ -40,3 +40,5 @@ // Protocol Buffers - Google's data interchange format

UPB_FORCEINLINE const char* upb_WireReader_ReadTag(
const char* ptr, uint32_t* tag, upb_EpsCopyInputStream* stream);
const char* ptr, uint32_t* tag, upb_EpsCopyInputStream* stream) {
return UPB_PRIVATE(_upb_WireReader_ReadTag)(ptr, tag, stream);
}

@@ -49,4 +51,6 @@ // Given a tag, returns the field number.

UPB_FORCEINLINE const char* upb_WireReader_ReadVarint(
const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream);
UPB_INLINE const char* upb_WireReader_ReadVarint(
const char* ptr, uint64_t* val, upb_EpsCopyInputStream* stream) {
return UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, val, stream);
}

@@ -72,3 +76,9 @@ // Skips data for a varint, returning a pointer past the end of the varint, or

UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size,
upb_EpsCopyInputStream* stream);
upb_EpsCopyInputStream* stream) {
uint64_t size64;
ptr = upb_WireReader_ReadVarint(ptr, &size64, stream);
if (!ptr || size64 >= INT32_MAX) return NULL;
*size = size64;
return ptr;
}

@@ -120,5 +130,3 @@ // Reads a fixed32 field, performing byte swapping if necessary.

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);
return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, 100, stream);
}

@@ -142,3 +150,3 @@

if (!ptr || !upb_EpsCopyInputStream_CheckSize(stream, ptr, size)) {
return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream);
return NULL;
}

@@ -152,6 +160,5 @@ ptr += size;

case kUpb_WireType_EndGroup:
// Should be handled before now.
return NULL; // Should be handled before now.
default:
// Unknown wire type.
return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream);
return NULL; // Unknown wire type.
}

@@ -158,0 +165,0 @@ }

// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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_UPB_UPB_BASE_ERROR_HANDLER_H__
#define GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__
#include <setjmp.h>
// Must be last.
#include "upb/port/def.inc"
// 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);
}
#include "upb/port/undef.inc"
#endif // GOOGLE_UPB_UPB_BASE_ERROR_HANDLER_H__
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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 "upb/mini_table/debug_string.h"
#include <inttypes.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include "upb/base/descriptor_constants.h"
#include "upb/hash/common.h"
#include "upb/hash/int_table.h"
#include "upb/mem/arena.h"
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/message.h"
#include "upb/port/vsnprintf_compat.h"
// Must be last.
#include "upb/port/def.inc"
typedef struct {
char* buf;
char* ptr;
char* end;
int overflow;
upb_Arena* arena;
int count;
// This table maps from a pointer to a 64-bit integer. The lower 32 bits are
// a unique ID for the object. The upper 32 bits are a flag that is 0x1
// if the object has already been printed.
upb_inttable inttable;
} upb_MiniTablePrinter;
UPB_PRINTF(2, 3)
static void upb_MiniTablePrinter_Printf(upb_MiniTablePrinter* p,
const char* fmt, ...) {
size_t n;
size_t have = p->end - p->ptr;
va_list args;
va_start(args, fmt);
n = _upb_vsnprintf(p->ptr, have, fmt, args);
va_end(args);
if (UPB_LIKELY(have > n)) {
p->ptr += n;
} else {
p->ptr = UPB_PTRADD(p->ptr, have);
p->overflow += (n - have);
}
}
static size_t upb_MiniTablePrinter_NullTerminate(upb_MiniTablePrinter* p,
size_t size) {
size_t ret = p->ptr - p->buf + p->overflow;
if (size > 0) {
if (p->ptr == p->end) p->ptr--;
*p->ptr = '\0';
}
return ret;
}
static int upb_MiniTablePrinter_InsertNext(upb_MiniTablePrinter* p,
const void* key, bool visited) {
uint64_t id = p->count++;
upb_inttable_insert(&p->inttable, (intptr_t)key,
upb_value_uint64(id | (visited ? 0x100000000 : 0)),
p->arena);
return id;
}
// Returns the ID of the object referenced by key, but does *not* mark the
// object as visited. This is used for printing a reference to another object
// that may or may not have been printed yet.
static int upb_MiniTablePrinter_GetIdForRef(upb_MiniTablePrinter* p,
const void* key) {
upb_value v;
if (upb_inttable_lookup(&p->inttable, (intptr_t)key, &v)) {
return (int)upb_value_getuint64(v);
}
return upb_MiniTablePrinter_InsertNext(p, key, false);
}
// Returns the ID of the object referenced by key, and marks the object as
// visited. This is used for printing the object itself.
static int upb_MiniTablePrinter_GetIdForEmit(upb_MiniTablePrinter* p,
const void* key) {
UPB_ASSERT(key);
upb_value v;
if (upb_inttable_lookup(&p->inttable, (intptr_t)key, &v)) {
uint64_t val = upb_value_getuint64(v);
if (val >> 32) return -1;
upb_inttable_replace(&p->inttable, (intptr_t)key,
upb_value_int64(val | 0x100000000));
return (int)val;
}
return upb_MiniTablePrinter_InsertNext(p, key, true);
}
static void upb_MiniTablePrinter_PrintEnum(upb_MiniTablePrinter* p,
const upb_MiniTableEnum* enum_) {
int id = upb_MiniTablePrinter_GetIdForEmit(p, enum_);
if (id < 0) return;
upb_MiniTablePrinter_Printf(p, "MiniTableEnum#%d {\n", id);
upb_MiniTablePrinter_Printf(p, " .mask_limit = %d\n",
enum_->UPB_PRIVATE(mask_limit));
upb_MiniTablePrinter_Printf(p, " .value_count = %d\n",
enum_->UPB_PRIVATE(value_count));
upb_MiniTablePrinter_Printf(p, " .values = {\n");
for (uint32_t i = 0; i < enum_->UPB_PRIVATE(mask_limit); i++) {
if (!upb_MiniTableEnum_CheckValue(enum_, i)) continue;
upb_MiniTablePrinter_Printf(p, " %d,\n", (int)i);
}
const uint32_t* start =
&enum_->UPB_PRIVATE(data)[enum_->UPB_PRIVATE(mask_limit) / 32];
for (uint32_t i = 0; i < enum_->UPB_PRIVATE(value_count); i++) {
upb_MiniTablePrinter_Printf(p, " %d,\n", (int)start[i]);
}
upb_MiniTablePrinter_Printf(p, " }\n");
upb_MiniTablePrinter_Printf(p, "}\n\n");
}
static void upb_MiniTablePrinter_PrintField(upb_MiniTablePrinter* p,
const upb_MiniTable* mini_table,
const upb_MiniTableField* field) {
upb_MiniTablePrinter_Printf(p, " MiniTableField {\n");
upb_MiniTablePrinter_Printf(p, " .number = %d\n",
field->UPB_PRIVATE(number));
upb_MiniTablePrinter_Printf(p, " .offset = %d\n",
field->UPB_PRIVATE(offset));
upb_MiniTablePrinter_Printf(p, " .presence = %d", field->presence);
if (field->presence > 0) {
upb_MiniTablePrinter_Printf(p, " (hasbit=%d)\n", field->presence);
} else if (field->presence < 0) {
upb_MiniTablePrinter_Printf(p, " (oneof_index=%d)\n", ~field->presence);
} else {
upb_MiniTablePrinter_Printf(p, " (no explicit presence)\n");
}
if (field->UPB_PRIVATE(submsg_ofs) != kUpb_NoSub) {
upb_MiniTablePrinter_Printf(p, " .submsg_ofs = %d\n",
field->UPB_PRIVATE(submsg_ofs));
}
upb_MiniTablePrinter_Printf(p, " .type = %d\n",
field->UPB_PRIVATE(descriptortype));
upb_MiniTablePrinter_Printf(p, " .mode = %02x (",
field->UPB_PRIVATE(mode));
switch (field->UPB_PRIVATE(mode) & kUpb_FieldMode_Mask) {
case kUpb_FieldMode_Scalar:
upb_MiniTablePrinter_Printf(p, "Scalar");
break;
case kUpb_FieldMode_Array:
upb_MiniTablePrinter_Printf(p, "Array");
break;
case kUpb_FieldMode_Map:
upb_MiniTablePrinter_Printf(p, "Map");
break;
}
switch (field->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift) {
case kUpb_FieldRep_1Byte:
upb_MiniTablePrinter_Printf(p, " | 1Byte");
break;
case kUpb_FieldRep_4Byte:
upb_MiniTablePrinter_Printf(p, " | 4Byte");
break;
case kUpb_FieldRep_8Byte:
upb_MiniTablePrinter_Printf(p, " | 8Byte");
break;
case kUpb_FieldRep_StringView:
upb_MiniTablePrinter_Printf(p, " | StringView");
break;
}
if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsPacked) {
upb_MiniTablePrinter_Printf(p, " | Packed");
}
if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension) {
upb_MiniTablePrinter_Printf(p, " | Extension");
}
if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsAlternate) {
upb_MiniTablePrinter_Printf(p, " | Alternate");
}
upb_MiniTablePrinter_Printf(p, ")\n");
if (field->UPB_PRIVATE(submsg_ofs) != kUpb_NoSub) {
if (upb_MiniTableField_CType(field) == kUpb_CType_Message) {
int id =
upb_MiniTablePrinter_GetIdForRef(p, upb_MiniTable_SubMessage(field));
upb_MiniTablePrinter_Printf(p, " .submsg = MiniTable#%d\n", id);
} else {
int id = upb_MiniTablePrinter_GetIdForRef(
p, upb_MiniTable_GetSubEnumTable(field));
upb_MiniTablePrinter_Printf(p, " .subenum = MiniTableEnum#%d\n", id);
}
}
upb_MiniTablePrinter_Printf(p, " },\n");
}
static void upb_MiniTablePrinter_PrintMessage(upb_MiniTablePrinter* p,
const upb_MiniTable* mini_table) {
int id = upb_MiniTablePrinter_GetIdForEmit(p, mini_table);
if (id < 0) return;
upb_MiniTablePrinter_Printf(p, "MiniTable#%d {\n", id);
upb_MiniTablePrinter_Printf(p, " .size = %d\n",
mini_table->UPB_PRIVATE(size));
upb_MiniTablePrinter_Printf(p, " .required_count = %d\n",
mini_table->UPB_PRIVATE(required_count));
upb_MiniTablePrinter_Printf(p, " .table_mask = %02x\n",
mini_table->UPB_PRIVATE(table_mask));
upb_MiniTablePrinter_Printf(p, " .dense_below = %d\n",
mini_table->UPB_PRIVATE(dense_below));
upb_MiniTablePrinter_Printf(p, " .ext = %02x (",
mini_table->UPB_PRIVATE(ext));
switch (mini_table->UPB_PRIVATE(ext) & 3) {
case kUpb_ExtMode_NonExtendable:
upb_MiniTablePrinter_Printf(p, "NonExtendable");
break;
case kUpb_ExtMode_Extendable:
upb_MiniTablePrinter_Printf(p, "Extendable");
break;
case kUpb_ExtMode_IsMessageSet:
upb_MiniTablePrinter_Printf(p, "MessageSet");
break;
case kUpb_ExtMode_IsMessageSet_ITEM:
upb_MiniTablePrinter_Printf(p, "MessageSetItem");
break;
}
if (mini_table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry) {
upb_MiniTablePrinter_Printf(p, " | MapEntry");
}
upb_MiniTablePrinter_Printf(p, ")\n");
upb_MiniTablePrinter_Printf(p, " .fields[%d] = {\n",
mini_table->UPB_PRIVATE(field_count));
for (int i = 0; i < mini_table->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i];
upb_MiniTablePrinter_PrintField(p, mini_table, field);
}
upb_MiniTablePrinter_Printf(p, " }\n");
int mask = (int8_t)mini_table->UPB_PRIVATE(table_mask);
if (mask != -1) {
int size = (mask >> 3) + 1;
upb_MiniTablePrinter_Printf(p, " .fasttable[%d] = {\n", size);
for (int i = 0; i < size; i++) {
const _upb_FastTable_Entry* entry =
&mini_table->UPB_PRIVATE(fasttable)[i];
upb_MiniTablePrinter_Printf(p, " FastTableEntry {\n");
upb_MiniTablePrinter_Printf(p, " .field_data = %016" PRIx64 ",\n",
entry->field_data);
upb_MiniTablePrinter_Printf(p, " .field_parser = %p\n",
entry->field_parser);
upb_MiniTablePrinter_Printf(p, " .field_number = %d\n",
(((int)entry->field_data >> 3) & 0xf) |
(((int)entry->field_data >> 4) & 0x7f0));
upb_MiniTablePrinter_Printf(p, " }\n");
}
upb_MiniTablePrinter_Printf(p, " }\n");
}
upb_MiniTablePrinter_Printf(p, "}\n\n");
for (int i = 0; i < mini_table->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i];
if (field->UPB_PRIVATE(submsg_ofs) == kUpb_NoSub) continue;
if (upb_MiniTableField_CType(field) == kUpb_CType_Message) {
upb_MiniTablePrinter_PrintMessage(p, upb_MiniTable_SubMessage(field));
} else {
upb_MiniTablePrinter_PrintEnum(p, upb_MiniTable_GetSubEnumTable(field));
}
}
}
size_t upb_MiniTable_DebugString(const upb_MiniTable* mini_table, char* buf,
size_t size) {
upb_MiniTablePrinter p = {buf, buf, buf + size, 0, upb_Arena_New(), 0};
if (!p.arena) return 0;
if (!upb_inttable_init(&p.inttable, p.arena)) return 0;
upb_MiniTablePrinter_PrintMessage(&p, mini_table);
upb_Arena_Free(p.arena);
return upb_MiniTablePrinter_NullTerminate(&p, size);
}
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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 UPB_MINI_TABLE_DEBUG_STRING_H_
#define UPB_MINI_TABLE_DEBUG_STRING_H_
#include <stddef.h>
#include "upb/mini_table/message.h"
#ifdef __cplusplus
extern "C" {
#endif
size_t upb_MiniTable_DebugString(const upb_MiniTable* mini_table, char* buf,
size_t size);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // UPB_MINI_TABLE_DEBUG_STRING_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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 "upb/mini_table/generated_registry.h"
#include <stdint.h>
#include "upb/mem/alloc.h"
#include "upb/mem/arena.h"
#include "upb/mini_table/extension.h"
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/internal/generated_registry.h" // IWYU pragma: keep
#include "upb/port/atomic.h"
// Must be last.
#include "upb/port/def.inc"
#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) {
// Comparing pointers to different objects is undefined behavior, so we
// convert them to uintptr_t and compare their values.
uintptr_t begin = (uintptr_t)entry->start;
uintptr_t end = (uintptr_t)entry->stop;
uintptr_t current = begin;
while (current < end) {
const upb_MiniTableExtension* ext =
(const upb_MiniTableExtension*)current;
// Sentinels and padding introduced by the linker can result in zeroed
// entries, so simply skip them.
if (upb_MiniTableExtension_Number(ext) == 0) {
// MSVC introduces padding that might not be sized exactly the same as
// upb_MiniTableExtension, so we can't iterate by sizeof. This is a
// valid thing for any linker to do, so it's safer to just always do it.
current += UPB_ALIGN_OF(upb_MiniTableExtension);
continue;
}
if (upb_ExtensionRegistry_Add(r, ext) !=
kUpb_ExtensionRegistryStatus_Ok) {
return false;
}
current += sizeof(upb_MiniTableExtension);
}
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(&registry->ref_count, memory_order_acquire);
// Try to increment the refcount, but only if it's not zero.
while (count > 0) {
if (upb_Atomic_CompareExchangeStrong(&registry->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(&registry->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(&registry->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(&registry->ref, &ref, new_ref,
memory_order_release,
memory_order_acquire)) {
// We won the race. Set the ref count to 1.
upb_Atomic_Store(&registry->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(&registry->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(&registry->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);
}
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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 UPB_MINI_TABLE_GENERATED_REGISTRY_H_
#define UPB_MINI_TABLE_GENERATED_REGISTRY_H_
#include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/internal/generated_registry.h"
// Must be last.
#include "upb/port/def.inc"
#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
#include "upb/port/undef.inc"
#endif // UPB_MINI_TABLE_GENERATED_REGISTRY_H_
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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 UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_
#define UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_
#include "upb/mini_table/internal/extension.h"
// Must be last.
#include "upb/port/def.inc"
#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
#include "upb/port/undef.inc"
#endif /* UPB_MINI_TABLE_INTERNAL_GENERATED_EXTENSION_REGISTRY_H_ */
// Protocol Buffers - Google's data interchange format
// Copyright 2025 Google LLC. 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 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>
#include "upb/base/error_handler.h"
#include "upb/base/string_view.h"
// Must be last.
#include "upb/port/def.inc"
#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
#include "upb/port/undef.inc"
#endif // UPB_WIRE_INTERNAL_EPS_COPY_INPUT_STREAM_H_

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display