- Each def type has its own .c file and its own .h file - Functions that require a builder context are declared in def_builder.h - The mini descriptor encoders have also been pulled into upb/reflection/ - upb/def.h, upb/def.hpp, upb/reflection.h, and upb/reflection.hpp are now deprecated stubs that point to the new headers PiperOrigin-RevId: 474459500pull/13171/head
parent
cbba1fb1e1
commit
00765002ff
44 changed files with 5825 additions and 4297 deletions
@ -0,0 +1,55 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
// Declarations common to all public def types.
|
||||
|
||||
#ifndef UPB_REFLECTION_COMMON_H_ |
||||
#define UPB_REFLECTION_COMMON_H_ |
||||
|
||||
#include "google/protobuf/descriptor.upb.h" |
||||
|
||||
typedef enum { kUpb_Syntax_Proto2 = 2, kUpb_Syntax_Proto3 = 3 } upb_Syntax; |
||||
|
||||
// Forward declarations for circular references.
|
||||
typedef struct upb_DefPool upb_DefPool; |
||||
typedef struct upb_EnumDef upb_EnumDef; |
||||
typedef struct upb_EnumValueDef upb_EnumValueDef; |
||||
typedef struct upb_ExtensionRange upb_ExtensionRange; |
||||
typedef struct upb_FieldDef upb_FieldDef; |
||||
typedef struct upb_FileDef upb_FileDef; |
||||
typedef struct upb_MessageDef upb_MessageDef; |
||||
typedef struct upb_MethodDef upb_MethodDef; |
||||
typedef struct upb_OneofDef upb_OneofDef; |
||||
typedef struct upb_ServiceDef upb_ServiceDef; |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
typedef struct upb_DefBuilder upb_DefBuilder; |
||||
|
||||
#endif /* UPB_REFLECTION_COMMON_H_ */ |
@ -0,0 +1,441 @@ |
||||
// Copyright (c) 2009-2021, Google LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google LLC nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef UPB_REFLECTION_DEF_HPP_ |
||||
#define UPB_REFLECTION_DEF_HPP_ |
||||
|
||||
#include <cstring> |
||||
#include <memory> |
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
#include "upb/reflection/def.h" |
||||
#include "upb/reflection/message.h" |
||||
#include "upb/upb.hpp" |
||||
|
||||
namespace upb { |
||||
|
||||
typedef upb_MessageValue MessageValue; |
||||
|
||||
class EnumDefPtr; |
||||
class FileDefPtr; |
||||
class MessageDefPtr; |
||||
class OneofDefPtr; |
||||
|
||||
// A upb::FieldDefPtr describes a single field in a message. It is most often
|
||||
// found as a part of a upb_MessageDef, but can also stand alone to represent
|
||||
// an extension.
|
||||
class FieldDefPtr { |
||||
public: |
||||
FieldDefPtr() : ptr_(nullptr) {} |
||||
explicit FieldDefPtr(const upb_FieldDef* ptr) : ptr_(ptr) {} |
||||
|
||||
const upb_FieldDef* ptr() const { return ptr_; } |
||||
explicit operator bool() const { return ptr_ != nullptr; } |
||||
|
||||
typedef upb_CType Type; |
||||
typedef upb_Label Label; |
||||
typedef upb_FieldType DescriptorType; |
||||
|
||||
const char* full_name() const { return upb_FieldDef_FullName(ptr_); } |
||||
|
||||
Type type() const { return upb_FieldDef_CType(ptr_); } |
||||
Label label() const { return upb_FieldDef_Label(ptr_); } |
||||
const char* name() const { return upb_FieldDef_Name(ptr_); } |
||||
const char* json_name() const { return upb_FieldDef_JsonName(ptr_); } |
||||
uint32_t number() const { return upb_FieldDef_Number(ptr_); } |
||||
bool is_extension() const { return upb_FieldDef_IsExtension(ptr_); } |
||||
|
||||
// For non-string, non-submessage fields, this indicates whether binary
|
||||
// protobufs are encoded in packed or non-packed format.
|
||||
//
|
||||
// Note: this accessor reflects the fact that "packed" has different defaults
|
||||
// depending on whether the proto is proto2 or proto3.
|
||||
bool packed() const { return upb_FieldDef_IsPacked(ptr_); } |
||||
|
||||
// An integer that can be used as an index into an array of fields for
|
||||
// whatever message this field belongs to. Guaranteed to be less than
|
||||
// f->containing_type()->field_count(). May only be accessed once the def has
|
||||
// been finalized.
|
||||
uint32_t index() const { return upb_FieldDef_Index(ptr_); } |
||||
|
||||
// The MessageDef to which this field belongs.
|
||||
//
|
||||
// If this field has been added to a MessageDef, that message can be retrieved
|
||||
// directly (this is always the case for frozen FieldDefs).
|
||||
//
|
||||
// If the field has not yet been added to a MessageDef, you can set the name
|
||||
// of the containing type symbolically instead. This is mostly useful for
|
||||
// extensions, where the extension is declared separately from the message.
|
||||
MessageDefPtr containing_type() const; |
||||
|
||||
// The OneofDef to which this field belongs, or NULL if this field is not part
|
||||
// of a oneof.
|
||||
OneofDefPtr containing_oneof() const; |
||||
|
||||
// The field's type according to the enum in descriptor.proto. This is not
|
||||
// the same as UPB_TYPE_*, because it distinguishes between (for example)
|
||||
// INT32 and SINT32, whereas our "type" enum does not. This return of
|
||||
// descriptor_type() is a function of type(), integer_format(), and
|
||||
// is_tag_delimited().
|
||||
DescriptorType descriptor_type() const { return upb_FieldDef_Type(ptr_); } |
||||
|
||||
// Convenient field type tests.
|
||||
bool IsSubMessage() const { return upb_FieldDef_IsSubMessage(ptr_); } |
||||
bool IsString() const { return upb_FieldDef_IsString(ptr_); } |
||||
bool IsSequence() const { return upb_FieldDef_IsRepeated(ptr_); } |
||||
bool IsPrimitive() const { return upb_FieldDef_IsPrimitive(ptr_); } |
||||
bool IsMap() const { return upb_FieldDef_IsMap(ptr_); } |
||||
|
||||
MessageValue default_value() const { return upb_FieldDef_Default(ptr_); } |
||||
|
||||
// Returns the enum or submessage def for this field, if any. The field's
|
||||
// type must match (ie. you may only call enum_subdef() for fields where
|
||||
// type() == kUpb_CType_Enum).
|
||||
EnumDefPtr enum_subdef() const; |
||||
MessageDefPtr message_subdef() const; |
||||
|
||||
private: |
||||
const upb_FieldDef* ptr_; |
||||
}; |
||||
|
||||
// Class that represents a oneof.
|
||||
class OneofDefPtr { |
||||
public: |
||||
OneofDefPtr() : ptr_(nullptr) {} |
||||
explicit OneofDefPtr(const upb_OneofDef* ptr) : ptr_(ptr) {} |
||||
|
||||
const upb_OneofDef* ptr() const { return ptr_; } |
||||
explicit operator bool() const { return ptr_ != nullptr; } |
||||
|
||||
// Returns the MessageDef that contains this OneofDef.
|
||||
MessageDefPtr containing_type() const; |
||||
|
||||
// Returns the name of this oneof.
|
||||
const char* name() const { return upb_OneofDef_Name(ptr_); } |
||||
|
||||
// Returns the number of fields in the oneof.
|
||||
int field_count() const { return upb_OneofDef_FieldCount(ptr_); } |
||||
FieldDefPtr field(int i) const { |
||||
return FieldDefPtr(upb_OneofDef_Field(ptr_, i)); |
||||
} |
||||
|
||||
// Looks up by name.
|
||||
FieldDefPtr FindFieldByName(const char* name, size_t len) const { |
||||
return FieldDefPtr(upb_OneofDef_LookupNameWithSize(ptr_, name, len)); |
||||
} |
||||
FieldDefPtr FindFieldByName(const char* name) const { |
||||
return FieldDefPtr(upb_OneofDef_LookupName(ptr_, name)); |
||||
} |
||||
|
||||
template <class T> |
||||
FieldDefPtr FindFieldByName(const T& str) const { |
||||
return FindFieldByName(str.c_str(), str.size()); |
||||
} |
||||
|
||||
// Looks up by tag number.
|
||||
FieldDefPtr FindFieldByNumber(uint32_t num) const { |
||||
return FieldDefPtr(upb_OneofDef_LookupNumber(ptr_, num)); |
||||
} |
||||
|
||||
private: |
||||
const upb_OneofDef* ptr_; |
||||
}; |
||||
|
||||
// Structure that describes a single .proto message type.
|
||||
class MessageDefPtr { |
||||
public: |
||||
MessageDefPtr() : ptr_(nullptr) {} |
||||
explicit MessageDefPtr(const upb_MessageDef* ptr) : ptr_(ptr) {} |
||||
|
||||
const upb_MessageDef* ptr() const { return ptr_; } |
||||
explicit operator bool() const { return ptr_ != nullptr; } |
||||
|
||||
FileDefPtr file() const; |
||||
|
||||
const char* full_name() const { return upb_MessageDef_FullName(ptr_); } |
||||
const char* name() const { return upb_MessageDef_Name(ptr_); } |
||||
|
||||
// The number of fields that belong to the MessageDef.
|
||||
int field_count() const { return upb_MessageDef_FieldCount(ptr_); } |
||||
FieldDefPtr field(int i) const { |
||||
return FieldDefPtr(upb_MessageDef_Field(ptr_, i)); |
||||
} |
||||
|
||||
// The number of oneofs that belong to the MessageDef.
|
||||
int oneof_count() const { return upb_MessageDef_OneofCount(ptr_); } |
||||
OneofDefPtr oneof(int i) const { |
||||
return OneofDefPtr(upb_MessageDef_Oneof(ptr_, i)); |
||||
} |
||||
|
||||
upb_Syntax syntax() const { return upb_MessageDef_Syntax(ptr_); } |
||||
|
||||
// These return null pointers if the field is not found.
|
||||
FieldDefPtr FindFieldByNumber(uint32_t number) const { |
||||
return FieldDefPtr(upb_MessageDef_FindFieldByNumber(ptr_, number)); |
||||
} |
||||
FieldDefPtr FindFieldByName(const char* name, size_t len) const { |
||||
return FieldDefPtr(upb_MessageDef_FindFieldByNameWithSize(ptr_, name, len)); |
||||
} |
||||
FieldDefPtr FindFieldByName(const char* name) const { |
||||
return FieldDefPtr(upb_MessageDef_FindFieldByName(ptr_, name)); |
||||
} |
||||
|
||||
template <class T> |
||||
FieldDefPtr FindFieldByName(const T& str) const { |
||||
return FindFieldByName(str.c_str(), str.size()); |
||||
} |
||||
|
||||
OneofDefPtr FindOneofByName(const char* name, size_t len) const { |
||||
return OneofDefPtr(upb_MessageDef_FindOneofByNameWithSize(ptr_, name, len)); |
||||
} |
||||
|
||||
OneofDefPtr FindOneofByName(const char* name) const { |
||||
return OneofDefPtr(upb_MessageDef_FindOneofByName(ptr_, name)); |
||||
} |
||||
|
||||
template <class T> |
||||
OneofDefPtr FindOneofByName(const T& str) const { |
||||
return FindOneofByName(str.c_str(), str.size()); |
||||
} |
||||
|
||||
// Is this message a map entry?
|
||||
bool mapentry() const { return upb_MessageDef_IsMapEntry(ptr_); } |
||||
|
||||
// Return the type of well known type message. kUpb_WellKnown_Unspecified for
|
||||
// non-well-known message.
|
||||
upb_WellKnown wellknowntype() const { |
||||
return upb_MessageDef_WellKnownType(ptr_); |
||||
} |
||||
|
||||
private: |
||||
class FieldIter { |
||||
public: |
||||
explicit FieldIter(const upb_MessageDef* m, int i) : m_(m), i_(i) {} |
||||
void operator++() { i_++; } |
||||
|
||||
FieldDefPtr operator*() { |
||||
return FieldDefPtr(upb_MessageDef_Field(m_, i_)); |
||||
} |
||||
bool operator!=(const FieldIter& other) { return i_ != other.i_; } |
||||
bool operator==(const FieldIter& other) { return i_ == other.i_; } |
||||
|
||||
private: |
||||
const upb_MessageDef* m_; |
||||
int i_; |
||||
}; |
||||
|
||||
class FieldAccessor { |
||||
public: |
||||
explicit FieldAccessor(const upb_MessageDef* md) : md_(md) {} |
||||
FieldIter begin() { return FieldIter(md_, 0); } |
||||
FieldIter end() { return FieldIter(md_, upb_MessageDef_FieldCount(md_)); } |
||||
|
||||
private: |
||||
const upb_MessageDef* md_; |
||||
}; |
||||
|
||||
class OneofIter { |
||||
public: |
||||
explicit OneofIter(const upb_MessageDef* m, int i) : m_(m), i_(i) {} |
||||
void operator++() { i_++; } |
||||
|
||||
OneofDefPtr operator*() { |
||||
return OneofDefPtr(upb_MessageDef_Oneof(m_, i_)); |
||||
} |
||||
bool operator!=(const OneofIter& other) { return i_ != other.i_; } |
||||
bool operator==(const OneofIter& other) { return i_ == other.i_; } |
||||
|
||||
private: |
||||
const upb_MessageDef* m_; |
||||
int i_; |
||||
}; |
||||
|
||||
class OneofAccessor { |
||||
public: |
||||
explicit OneofAccessor(const upb_MessageDef* md) : md_(md) {} |
||||
OneofIter begin() { return OneofIter(md_, 0); } |
||||
OneofIter end() { return OneofIter(md_, upb_MessageDef_OneofCount(md_)); } |
||||
|
||||
private: |
||||
const upb_MessageDef* md_; |
||||
}; |
||||
|
||||
public: |
||||
FieldAccessor fields() const { return FieldAccessor(ptr()); } |
||||
OneofAccessor oneofs() const { return OneofAccessor(ptr()); } |
||||
|
||||
private: |
||||
const upb_MessageDef* ptr_; |
||||
}; |
||||
|
||||
class EnumValDefPtr { |
||||
public: |
||||
EnumValDefPtr() : ptr_(nullptr) {} |
||||
explicit EnumValDefPtr(const upb_EnumValueDef* ptr) : ptr_(ptr) {} |
||||
|
||||
int32_t number() const { return upb_EnumValueDef_Number(ptr_); } |
||||
const char* full_name() const { return upb_EnumValueDef_FullName(ptr_); } |
||||
const char* name() const { return upb_EnumValueDef_Name(ptr_); } |
||||
|
||||
private: |
||||
const upb_EnumValueDef* ptr_; |
||||
}; |
||||
|
||||
class EnumDefPtr { |
||||
public: |
||||
EnumDefPtr() : ptr_(nullptr) {} |
||||
explicit EnumDefPtr(const upb_EnumDef* ptr) : ptr_(ptr) {} |
||||
|
||||
const upb_EnumDef* ptr() const { return ptr_; } |
||||
explicit operator bool() const { return ptr_ != nullptr; } |
||||
|
||||
const char* full_name() const { return upb_EnumDef_FullName(ptr_); } |
||||
const char* name() const { return upb_EnumDef_Name(ptr_); } |
||||
|
||||
// The value that is used as the default when no field default is specified.
|
||||
// If not set explicitly, the first value that was added will be used.
|
||||
// The default value must be a member of the enum.
|
||||
// Requires that value_count() > 0.
|
||||
int32_t default_value() const { return upb_EnumDef_Default(ptr_); } |
||||
|
||||
// Returns the number of values currently defined in the enum. Note that
|
||||
// multiple names can refer to the same number, so this may be greater than
|
||||
// the total number of unique numbers.
|
||||
int value_count() const { return upb_EnumDef_ValueCount(ptr_); } |
||||
|
||||
// Lookups from name to integer, returning true if found.
|
||||
EnumValDefPtr FindValueByName(const char* name) const { |
||||
return EnumValDefPtr(upb_EnumDef_FindValueByName(ptr_, name)); |
||||
} |
||||
|
||||
// Finds the name corresponding to the given number, or NULL if none was
|
||||
// found. If more than one name corresponds to this number, returns the
|
||||
// first one that was added.
|
||||
EnumValDefPtr FindValueByNumber(int32_t num) const { |
||||
return EnumValDefPtr(upb_EnumDef_FindValueByNumber(ptr_, num)); |
||||
} |
||||
|
||||
private: |
||||
const upb_EnumDef* ptr_; |
||||
}; |
||||
|
||||
// Class that represents a .proto file with some things defined in it.
|
||||
//
|
||||
// Many users won't care about FileDefs, but they are necessary if you want to
|
||||
// read the values of file-level options.
|
||||
class FileDefPtr { |
||||
public: |
||||
explicit FileDefPtr(const upb_FileDef* ptr) : ptr_(ptr) {} |
||||
|
||||
const upb_FileDef* ptr() const { return ptr_; } |
||||
explicit operator bool() const { return ptr_ != nullptr; } |
||||
|
||||
// Get/set name of the file (eg. "foo/bar.proto").
|
||||
const char* name() const { return upb_FileDef_Name(ptr_); } |
||||
|
||||
// Package name for definitions inside the file (eg. "foo.bar").
|
||||
const char* package() const { return upb_FileDef_Package(ptr_); } |
||||
|
||||
// Syntax for the file. Defaults to proto2.
|
||||
upb_Syntax syntax() const { return upb_FileDef_Syntax(ptr_); } |
||||
|
||||
// Get the list of dependencies from the file. These are returned in the
|
||||
// order that they were added to the FileDefPtr.
|
||||
int dependency_count() const { return upb_FileDef_DependencyCount(ptr_); } |
||||
const FileDefPtr dependency(int index) const { |
||||
return FileDefPtr(upb_FileDef_Dependency(ptr_, index)); |
||||
} |
||||
|
||||
private: |
||||
const upb_FileDef* ptr_; |
||||
}; |
||||
|
||||
// Non-const methods in upb::DefPool are NOT thread-safe.
|
||||
class DefPool { |
||||
public: |
||||
DefPool() : ptr_(upb_DefPool_New(), upb_DefPool_Free) {} |
||||
explicit DefPool(upb_DefPool* s) : ptr_(s, upb_DefPool_Free) {} |
||||
|
||||
const upb_DefPool* ptr() const { return ptr_.get(); } |
||||
upb_DefPool* ptr() { return ptr_.get(); } |
||||
|
||||
// Finds an entry in the symbol table with this exact name. If not found,
|
||||
// returns NULL.
|
||||
MessageDefPtr FindMessageByName(const char* sym) const { |
||||
return MessageDefPtr(upb_DefPool_FindMessageByName(ptr_.get(), sym)); |
||||
} |
||||
|
||||
EnumDefPtr FindEnumByName(const char* sym) const { |
||||
return EnumDefPtr(upb_DefPool_FindEnumByName(ptr_.get(), sym)); |
||||
} |
||||
|
||||
FileDefPtr FindFileByName(const char* name) const { |
||||
return FileDefPtr(upb_DefPool_FindFileByName(ptr_.get(), name)); |
||||
} |
||||
|
||||
// TODO: iteration?
|
||||
|
||||
// Adds the given serialized FileDescriptorProto to the pool.
|
||||
FileDefPtr AddFile(const google_protobuf_FileDescriptorProto* file_proto, |
||||
Status* status) { |
||||
return FileDefPtr( |
||||
upb_DefPool_AddFile(ptr_.get(), file_proto, status->ptr())); |
||||
} |
||||
|
||||
private: |
||||
std::unique_ptr<upb_DefPool, decltype(&upb_DefPool_Free)> ptr_; |
||||
}; |
||||
|
||||
// TODO(b/236632406): This typedef is deprecated. Delete it.
|
||||
using SymbolTable = DefPool; |
||||
|
||||
inline FileDefPtr MessageDefPtr::file() const { |
||||
return FileDefPtr(upb_MessageDef_File(ptr_)); |
||||
} |
||||
|
||||
inline MessageDefPtr FieldDefPtr::message_subdef() const { |
||||
return MessageDefPtr(upb_FieldDef_MessageSubDef(ptr_)); |
||||
} |
||||
|
||||
inline MessageDefPtr FieldDefPtr::containing_type() const { |
||||
return MessageDefPtr(upb_FieldDef_ContainingType(ptr_)); |
||||
} |
||||
|
||||
inline MessageDefPtr OneofDefPtr::containing_type() const { |
||||
return MessageDefPtr(upb_OneofDef_ContainingType(ptr_)); |
||||
} |
||||
|
||||
inline OneofDefPtr FieldDefPtr::containing_oneof() const { |
||||
return OneofDefPtr(upb_FieldDef_ContainingOneof(ptr_)); |
||||
} |
||||
|
||||
inline EnumDefPtr FieldDefPtr::enum_subdef() const { |
||||
return EnumDefPtr(upb_FieldDef_EnumSubDef(ptr_)); |
||||
} |
||||
|
||||
} // namespace upb
|
||||
|
||||
#endif // UPB_REFLECTION_DEF_HPP_
|
@ -0,0 +1,338 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
|
||||
#include <string.h> |
||||
|
||||
#include "upb/reflection/def_pool.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/field_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
/* The upb core does not generally have a concept of default instances. However
|
||||
* for descriptor options we make an exception since the max size is known and |
||||
* modest (<200 bytes). All types can share a default instance since it is |
||||
* initialized to zeroes. |
||||
* |
||||
* We have to allocate an extra pointer for upb's internal metadata. */ |
||||
static const char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0}; |
||||
const char* kUpbDefOptDefault = &opt_default_buf[sizeof(void*)]; |
||||
|
||||
const char* _upb_DefBuilder_FullToShort(const char* fullname) { |
||||
const char* p; |
||||
|
||||
if (fullname == NULL) { |
||||
return NULL; |
||||
} else if ((p = strrchr(fullname, '.')) == NULL) { |
||||
/* No '.' in the name, return the full string. */ |
||||
return fullname; |
||||
} else { |
||||
/* Return one past the last '.'. */ |
||||
return p + 1; |
||||
} |
||||
} |
||||
|
||||
void _upb_DefBuilder_Errf(upb_DefBuilder* ctx, const char* fmt, ...) { |
||||
va_list argp; |
||||
va_start(argp, fmt); |
||||
upb_Status_VSetErrorFormat(ctx->status, fmt, argp); |
||||
va_end(argp); |
||||
UPB_LONGJMP(ctx->err, 1); |
||||
} |
||||
|
||||
void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx) { |
||||
upb_Status_SetErrorMessage(ctx->status, "out of memory"); |
||||
UPB_LONGJMP(ctx->err, 1); |
||||
} |
||||
|
||||
const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx, |
||||
const char* prefix, |
||||
upb_StringView name) { |
||||
if (prefix) { |
||||
// ret = prefix + '.' + name;
|
||||
size_t n = strlen(prefix); |
||||
char* ret = _upb_DefBuilder_Alloc(ctx, n + name.size + 2); |
||||
strcpy(ret, prefix); |
||||
ret[n] = '.'; |
||||
memcpy(&ret[n + 1], name.data, name.size); |
||||
ret[n + 1 + name.size] = '\0'; |
||||
return ret; |
||||
} else { |
||||
char* ret = upb_strdup2(name.data, name.size, ctx->arena); |
||||
if (!ret) _upb_DefBuilder_OomErr(ctx); |
||||
return ret; |
||||
} |
||||
} |
||||
|
||||
static bool remove_component(char* base, size_t* len) { |
||||
if (*len == 0) return false; |
||||
|
||||
for (size_t i = *len - 1; i > 0; i--) { |
||||
if (base[i] == '.') { |
||||
*len = i; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
*len = 0; |
||||
return true; |
||||
} |
||||
|
||||
const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, |
||||
const char* from_name_dbg, |
||||
const char* base, upb_StringView sym, |
||||
upb_deftype_t* type) { |
||||
if (sym.size == 0) goto notfound; |
||||
upb_value v; |
||||
if (sym.data[0] == '.') { |
||||
/* Symbols starting with '.' are absolute, so we do a single lookup.
|
||||
* Slice to omit the leading '.' */ |
||||
if (!_upb_DefPool_LookupAny2(ctx->symtab, sym.data + 1, sym.size - 1, &v)) { |
||||
goto notfound; |
||||
} |
||||
} else { |
||||
/* Remove components from base until we find an entry or run out. */ |
||||
size_t baselen = base ? strlen(base) : 0; |
||||
char* tmp = malloc(sym.size + baselen + 1); |
||||
while (1) { |
||||
char* p = tmp; |
||||
if (baselen) { |
||||
memcpy(p, base, baselen); |
||||
p[baselen] = '.'; |
||||
p += baselen + 1; |
||||
} |
||||
memcpy(p, sym.data, sym.size); |
||||
p += sym.size; |
||||
if (_upb_DefPool_LookupAny2(ctx->symtab, tmp, p - tmp, &v)) { |
||||
break; |
||||
} |
||||
if (!remove_component(tmp, &baselen)) { |
||||
free(tmp); |
||||
goto notfound; |
||||
} |
||||
} |
||||
free(tmp); |
||||
} |
||||
|
||||
*type = _upb_DefType_Type(v); |
||||
return _upb_DefType_Unpack(v, *type); |
||||
|
||||
notfound: |
||||
_upb_DefBuilder_Errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'", |
||||
UPB_STRINGVIEW_ARGS(sym)); |
||||
} |
||||
|
||||
const void* _upb_DefBuilder_Resolve(upb_DefBuilder* ctx, |
||||
const char* from_name_dbg, const char* base, |
||||
upb_StringView sym, upb_deftype_t type) { |
||||
upb_deftype_t found_type; |
||||
const void* ret = |
||||
_upb_DefBuilder_ResolveAny(ctx, from_name_dbg, base, sym, &found_type); |
||||
if (ret && found_type != type) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"type mismatch when resolving %s: couldn't find " |
||||
"name " UPB_STRINGVIEW_FORMAT " with type=%d", |
||||
from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (int)type); |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
// Per ASCII this will lower-case a letter. If the result is a letter, the
|
||||
// input was definitely a letter. If the output is not a letter, this may
|
||||
// have transformed the character unpredictably.
|
||||
static char upb_ascii_lower(char ch) { return ch | 0x20; } |
||||
|
||||
// isalpha() etc. from <ctype.h> are locale-dependent, which we don't want.
|
||||
static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) { |
||||
return low <= c && c <= high; |
||||
} |
||||
|
||||
static bool upb_isletter(char c) { |
||||
char lower = upb_ascii_lower(c); |
||||
return upb_isbetween(lower, 'a', 'z') || c == '_'; |
||||
} |
||||
|
||||
static bool upb_isalphanum(char c) { |
||||
return upb_isletter(c) || upb_isbetween(c, '0', '9'); |
||||
} |
||||
|
||||
static bool TryGetChar(const char** src, const char* end, char* ch) { |
||||
if (*src == end) return false; |
||||
*ch = **src; |
||||
*src += 1; |
||||
return true; |
||||
} |
||||
|
||||
static char TryGetHexDigit(const char** src, const char* end) { |
||||
char ch; |
||||
if (!TryGetChar(src, end, &ch)) return -1; |
||||
if ('0' <= ch && ch <= '9') { |
||||
return ch - '0'; |
||||
} |
||||
ch = upb_ascii_lower(ch); |
||||
if ('a' <= ch && ch <= 'f') { |
||||
return ch - 'a' + 0xa; |
||||
} |
||||
*src -= 1; // Char wasn't actually a hex digit.
|
||||
return -1; |
||||
} |
||||
|
||||
static char upb_DefBuilder_ParseHexEscape(upb_DefBuilder* ctx, |
||||
const upb_FieldDef* f, |
||||
const char** src, const char* end) { |
||||
char hex_digit = TryGetHexDigit(src, end); |
||||
if (hex_digit < 0) { |
||||
_upb_DefBuilder_Errf( |
||||
ctx, "\\x cannot be followed by non-hex digit in field '%s' default", |
||||
upb_FieldDef_FullName(f)); |
||||
return 0; |
||||
} |
||||
unsigned int ret = hex_digit; |
||||
while ((hex_digit = TryGetHexDigit(src, end)) >= 0) { |
||||
ret = (ret << 4) | hex_digit; |
||||
} |
||||
if (ret > 0xff) { |
||||
_upb_DefBuilder_Errf(ctx, "Value of hex escape in field %s exceeds 8 bits", |
||||
upb_FieldDef_FullName(f)); |
||||
return 0; |
||||
} |
||||
return ret; |
||||
} |
||||
|
||||
static char TryGetOctalDigit(const char** src, const char* end) { |
||||
char ch; |
||||
if (!TryGetChar(src, end, &ch)) return -1; |
||||
if ('0' <= ch && ch <= '7') { |
||||
return ch - '0'; |
||||
} |
||||
*src -= 1; // Char wasn't actually an octal digit.
|
||||
return -1; |
||||
} |
||||
|
||||
static char upb_DefBuilder_ParseOctalEscape(upb_DefBuilder* ctx, |
||||
const upb_FieldDef* f, |
||||
const char** src, const char* end) { |
||||
char ch = 0; |
||||
for (int i = 0; i < 3; i++) { |
||||
char digit; |
||||
if ((digit = TryGetOctalDigit(src, end)) >= 0) { |
||||
ch = (ch << 3) | digit; |
||||
} |
||||
} |
||||
return ch; |
||||
} |
||||
|
||||
char _upb_DefBuilder_ParseEscape(upb_DefBuilder* ctx, const upb_FieldDef* f, |
||||
const char** src, const char* end) { |
||||
char ch; |
||||
if (!TryGetChar(src, end, &ch)) { |
||||
_upb_DefBuilder_Errf(ctx, "unterminated escape sequence in field %s", |
||||
upb_FieldDef_FullName(f)); |
||||
return 0; |
||||
} |
||||
switch (ch) { |
||||
case 'a': |
||||
return '\a'; |
||||
case 'b': |
||||
return '\b'; |
||||
case 'f': |
||||
return '\f'; |
||||
case 'n': |
||||
return '\n'; |
||||
case 'r': |
||||
return '\r'; |
||||
case 't': |
||||
return '\t'; |
||||
case 'v': |
||||
return '\v'; |
||||
case '\\': |
||||
return '\\'; |
||||
case '\'': |
||||
return '\''; |
||||
case '\"': |
||||
return '\"'; |
||||
case '?': |
||||
return '\?'; |
||||
case 'x': |
||||
case 'X': |
||||
return upb_DefBuilder_ParseHexEscape(ctx, f, src, end); |
||||
case '0': |
||||
case '1': |
||||
case '2': |
||||
case '3': |
||||
case '4': |
||||
case '5': |
||||
case '6': |
||||
case '7': |
||||
*src -= 1; |
||||
return upb_DefBuilder_ParseOctalEscape(ctx, f, src, end); |
||||
} |
||||
_upb_DefBuilder_Errf(ctx, "Unknown escape sequence: \\%c", ch); |
||||
} |
||||
|
||||
void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, |
||||
bool full) { |
||||
const char* str = name.data; |
||||
const size_t len = name.size; |
||||
bool start = true; |
||||
for (size_t i = 0; i < len; i++) { |
||||
const char c = str[i]; |
||||
if (c == '.') { |
||||
if (start || !full) { |
||||
_upb_DefBuilder_Errf( |
||||
ctx, "invalid name: unexpected '.' (" UPB_STRINGVIEW_FORMAT ")", |
||||
UPB_STRINGVIEW_ARGS(name)); |
||||
} |
||||
start = true; |
||||
} else if (start) { |
||||
if (!upb_isletter(c)) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"invalid name: path components must start with a " |
||||
"letter (" UPB_STRINGVIEW_FORMAT ")", |
||||
UPB_STRINGVIEW_ARGS(name)); |
||||
} |
||||
start = false; |
||||
} else if (!upb_isalphanum(c)) { |
||||
_upb_DefBuilder_Errf( |
||||
ctx, |
||||
"invalid name: non-alphanumeric character (" UPB_STRINGVIEW_FORMAT |
||||
")", |
||||
UPB_STRINGVIEW_ARGS(name)); |
||||
} |
||||
} |
||||
if (start) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"invalid name: empty part (" UPB_STRINGVIEW_FORMAT ")", |
||||
UPB_STRINGVIEW_ARGS(name)); |
||||
} |
||||
|
||||
// We should never reach this point.
|
||||
UPB_ASSERT(false); |
||||
} |
@ -0,0 +1,174 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#ifndef UPB_REFLECTION_DEF_BUILDER_H_ |
||||
#define UPB_REFLECTION_DEF_BUILDER_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
#include "upb/reflection/def_pool.h" |
||||
#include "upb/reflection/def_type.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
// We want to copy the options verbatim into the destination options proto.
|
||||
// We use serialize+parse as our deep copy.
|
||||
#define UBP_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(pb, size, _upb_DefBuilder_Arena(ctx)); \
|
||||
if (!target) _upb_DefBuilder_OomErr(ctx); \
|
||||
} else { \
|
||||
target = (const google_protobuf_##options_type*)kUpbDefOptDefault; \
|
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct upb_DefBuilder { |
||||
upb_DefPool* symtab; |
||||
upb_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_MiniTable_File* layout; // NULL if we should build layouts.
|
||||
int enum_count; // Count of enums built so far.
|
||||
int msg_count; // Count of messages built so far.
|
||||
int ext_count; // Count of extensions built so far.
|
||||
jmp_buf err; // longjmp() on error.
|
||||
}; |
||||
|
||||
extern const char* kUpbDefOptDefault; |
||||
|
||||
UPB_NORETURN void _upb_DefBuilder_Errf(upb_DefBuilder* ctx, const char* fmt, |
||||
...) UPB_PRINTF(2, 3); |
||||
UPB_NORETURN void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx); |
||||
|
||||
const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx, |
||||
const char* prefix, |
||||
upb_StringView name); |
||||
|
||||
// Given a symbol and the base symbol inside which it is defined,
|
||||
// find the symbol's definition.
|
||||
const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, |
||||
const char* from_name_dbg, |
||||
const char* base, upb_StringView sym, |
||||
upb_deftype_t* type); |
||||
|
||||
const void* _upb_DefBuilder_Resolve(upb_DefBuilder* ctx, |
||||
const char* from_name_dbg, const char* base, |
||||
upb_StringView sym, upb_deftype_t type); |
||||
|
||||
char _upb_DefBuilder_ParseEscape(upb_DefBuilder* ctx, const upb_FieldDef* f, |
||||
const char** src, const char* end); |
||||
|
||||
const char* _upb_DefBuilder_FullToShort(const char* fullname); |
||||
|
||||
UPB_INLINE void* _upb_DefBuilder_Alloc(upb_DefBuilder* ctx, size_t bytes) { |
||||
if (bytes == 0) return NULL; |
||||
void* ret = upb_Arena_Malloc(ctx->arena, bytes); |
||||
if (!ret) _upb_DefBuilder_OomErr(ctx); |
||||
return ret; |
||||
} |
||||
|
||||
// Adds a symbol |v| to the symtab, which must be a def pointer previously
|
||||
// packed with pack_def(). The def's pointer to upb_FileDef* must be set before
|
||||
// adding, so we know which entries to remove if building this file fails.
|
||||
UPB_INLINE void _upb_DefBuilder_Add(upb_DefBuilder* ctx, const char* name, |
||||
upb_value v) { |
||||
// TODO: table should support an operation "tryinsert" to avoid the double
|
||||
// lookup.
|
||||
if (_upb_DefPool_Contains(ctx->symtab, name)) { |
||||
_upb_DefBuilder_Errf(ctx, "duplicate symbol '%s'", name); |
||||
} |
||||
bool ok = _upb_DefPool_Insert(ctx->symtab, name, v); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
} |
||||
|
||||
UPB_INLINE upb_Arena* _upb_DefBuilder_Arena(const upb_DefBuilder* ctx) { |
||||
return ctx->arena; |
||||
} |
||||
|
||||
UPB_INLINE upb_FileDef* _upb_DefBuilder_File(const upb_DefBuilder* ctx) { |
||||
return ctx->file; |
||||
} |
||||
|
||||
// This version of CheckIdent() is only called by other, faster versions after
|
||||
// they detect a parsing error.
|
||||
void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, |
||||
bool full); |
||||
|
||||
// Verify a relative identifier string. The loop is branchless for speed.
|
||||
UPB_INLINE void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx, |
||||
upb_StringView name) { |
||||
bool good = name.size > 0; |
||||
|
||||
for (size_t i = 0; i < name.size; i++) { |
||||
const char c = name.data[i]; |
||||
const char d = c | 0x20; // force lowercase
|
||||
const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); |
||||
const bool is_numer = ('0' <= c) & (c <= '9') & (i != 0); |
||||
|
||||
good &= is_alpha | is_numer; |
||||
} |
||||
|
||||
if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false); |
||||
} |
||||
|
||||
// Verify a full identifier string. This is slightly more complicated than
|
||||
// verifying a relative identifier string because we must track '.' chars.
|
||||
UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, |
||||
upb_StringView name) { |
||||
bool good = name.size > 0; |
||||
bool start = true; |
||||
|
||||
for (size_t i = 0; i < name.size; i++) { |
||||
const char c = name.data[i]; |
||||
const char d = c | 0x20; // force lowercase
|
||||
const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); |
||||
const bool is_numer = ('0' <= c) & (c <= '9') & !start; |
||||
const bool is_dot = (c == '.') & !start; |
||||
|
||||
good &= is_alpha | is_numer | is_dot; |
||||
start = is_dot; |
||||
} |
||||
|
||||
if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_DEF_BUILDER_H_ */ |
@ -0,0 +1,85 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2022, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
|
||||
#include "gtest/gtest.h" |
||||
#include "upb/reflection/def.hpp" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct IdentTest { |
||||
const char* text; |
||||
bool ok; |
||||
}; |
||||
|
||||
static const std::vector<IdentTest> FullIdentTests = { |
||||
{"foo.bar", true}, {"foo.", true}, {"foo", true}, |
||||
|
||||
{"foo.7bar", false}, {".foo", false}, {"#", false}, |
||||
{".", false}, {"", false}, |
||||
}; |
||||
|
||||
static const std::vector<IdentTest> NotFullIdentTests = { |
||||
{"foo", true}, {"foo1", true}, |
||||
|
||||
{"foo.bar", false}, {"1foo", false}, {"#", false}, |
||||
{".", false}, {"", false}, |
||||
}; |
||||
|
||||
TEST(DefBuilder, TestIdents) { |
||||
upb_StringView sv; |
||||
upb_Status status; |
||||
upb_DefBuilder ctx; |
||||
ctx.status = &status; |
||||
upb_Status_Clear(&status); |
||||
|
||||
for (const auto& test : FullIdentTests) { |
||||
sv.data = test.text; |
||||
sv.size = strlen(test.text); |
||||
|
||||
if (UPB_SETJMP(ctx.err)) { |
||||
EXPECT_FALSE(test.ok); |
||||
} else { |
||||
_upb_DefBuilder_CheckIdentFull(&ctx, sv); |
||||
EXPECT_TRUE(test.ok); |
||||
} |
||||
} |
||||
|
||||
for (const auto& test : NotFullIdentTests) { |
||||
sv.data = test.text; |
||||
sv.size = strlen(test.text); |
||||
|
||||
if (UPB_SETJMP(ctx.err)) { |
||||
EXPECT_FALSE(test.ok); |
||||
} else { |
||||
_upb_DefBuilder_CheckIdentNotFull(&ctx, sv); |
||||
EXPECT_TRUE(test.ok); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,437 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/def_pool.h" |
||||
|
||||
#include <stdio.h> |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/enum_def.h" |
||||
#include "upb/reflection/enum_value_def.h" |
||||
#include "upb/reflection/field_def.h" |
||||
#include "upb/reflection/file_def.h" |
||||
#include "upb/reflection/message_def.h" |
||||
#include "upb/reflection/service_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_DefPool { |
||||
upb_Arena* arena; |
||||
upb_strtable syms; // full_name -> packed def ptr
|
||||
upb_strtable files; // file_name -> (upb_FileDef*)
|
||||
upb_inttable exts; // (upb_MiniTable_Extension*) -> (upb_FieldDef*)
|
||||
upb_ExtensionRegistry* extreg; |
||||
size_t bytes_loaded; |
||||
}; |
||||
|
||||
void upb_DefPool_Free(upb_DefPool* s) { |
||||
upb_Arena_Free(s->arena); |
||||
upb_gfree(s); |
||||
} |
||||
|
||||
upb_DefPool* upb_DefPool_New(void) { |
||||
upb_DefPool* s = upb_gmalloc(sizeof(*s)); |
||||
if (!s) return NULL; |
||||
|
||||
s->arena = upb_Arena_New(); |
||||
s->bytes_loaded = 0; |
||||
|
||||
if (!upb_strtable_init(&s->syms, 32, s->arena)) goto err; |
||||
if (!upb_strtable_init(&s->files, 4, s->arena)) goto err; |
||||
if (!upb_inttable_init(&s->exts, s->arena)) goto err; |
||||
|
||||
s->extreg = upb_ExtensionRegistry_New(s->arena); |
||||
if (!s->extreg) goto err; |
||||
|
||||
return s; |
||||
|
||||
err: |
||||
upb_Arena_Free(s->arena); |
||||
upb_gfree(s); |
||||
return NULL; |
||||
} |
||||
|
||||
bool _upb_DefPool_Contains(const upb_DefPool* s, const char* sym) { |
||||
return upb_strtable_lookup(&s->syms, sym, NULL); |
||||
} |
||||
|
||||
bool _upb_DefPool_Insert(upb_DefPool* s, const char* sym, upb_value v) { |
||||
return _upb_DefPool_Insert2(s, sym, strlen(sym), v); |
||||
} |
||||
|
||||
bool _upb_DefPool_Insert2(upb_DefPool* s, const char* sym, size_t size, |
||||
upb_value v) { |
||||
return upb_strtable_insert(&s->syms, sym, size, v, s->arena); |
||||
} |
||||
|
||||
bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTable_Extension* ext, |
||||
upb_FieldDef* f, upb_Arena* a) { |
||||
return upb_inttable_insert(&s->exts, (uintptr_t)ext, upb_value_constptr(f), |
||||
a); |
||||
} |
||||
|
||||
static const void* _upb_DefPool_Lookup(const upb_DefPool* s, const char* sym, |
||||
upb_deftype_t type) { |
||||
return _upb_DefPool_Lookup2(s, sym, strlen(sym), type); |
||||
} |
||||
|
||||
const void* _upb_DefPool_Lookup2(const upb_DefPool* s, const char* sym, |
||||
size_t size, upb_deftype_t type) { |
||||
upb_value v; |
||||
return upb_strtable_lookup2(&s->syms, sym, size, &v) |
||||
? _upb_DefType_Unpack(v, type) |
||||
: NULL; |
||||
} |
||||
|
||||
bool _upb_DefPool_LookupAny2(const upb_DefPool* s, const char* sym, size_t size, |
||||
upb_value* v) { |
||||
return upb_strtable_lookup2(&s->syms, sym, size, v); |
||||
} |
||||
|
||||
upb_ExtensionRegistry* _upb_DefPool_ExtReg(const upb_DefPool* s) { |
||||
return s->extreg; |
||||
} |
||||
|
||||
const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, |
||||
const char* sym) { |
||||
return _upb_DefPool_Lookup(s, sym, UPB_DEFTYPE_MSG); |
||||
} |
||||
|
||||
const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( |
||||
const upb_DefPool* s, const char* sym, size_t len) { |
||||
return _upb_DefPool_Lookup2(s, sym, len, UPB_DEFTYPE_MSG); |
||||
} |
||||
|
||||
const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, |
||||
const char* sym) { |
||||
return _upb_DefPool_Lookup(s, sym, UPB_DEFTYPE_ENUM); |
||||
} |
||||
|
||||
const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s, |
||||
const char* sym) { |
||||
return _upb_DefPool_Lookup(s, sym, UPB_DEFTYPE_ENUMVAL); |
||||
} |
||||
|
||||
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, |
||||
const char* name) { |
||||
upb_value v; |
||||
return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v) |
||||
: NULL; |
||||
} |
||||
|
||||
const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, |
||||
const char* name, |
||||
size_t len) { |
||||
upb_value v; |
||||
return upb_strtable_lookup2(&s->files, name, len, &v) |
||||
? upb_value_getconstptr(v) |
||||
: NULL; |
||||
} |
||||
|
||||
const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( |
||||
const upb_DefPool* s, const char* name, size_t size) { |
||||
upb_value v; |
||||
if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL; |
||||
|
||||
switch (_upb_DefType_Type(v)) { |
||||
case UPB_DEFTYPE_FIELD: |
||||
return _upb_DefType_Unpack(v, UPB_DEFTYPE_FIELD); |
||||
case UPB_DEFTYPE_MSG: { |
||||
const upb_MessageDef* m = _upb_DefType_Unpack(v, UPB_DEFTYPE_MSG); |
||||
return _upb_MessageDef_InMessageSet(m) |
||||
? upb_MessageDef_NestedExtension(m, 0) |
||||
: NULL; |
||||
} |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, |
||||
const char* sym) { |
||||
return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym)); |
||||
} |
||||
|
||||
const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, |
||||
const char* name) { |
||||
return _upb_DefPool_Lookup(s, name, UPB_DEFTYPE_SERVICE); |
||||
} |
||||
|
||||
const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( |
||||
const upb_DefPool* s, const char* name, size_t size) { |
||||
return _upb_DefPool_Lookup2(s, name, size, UPB_DEFTYPE_SERVICE); |
||||
} |
||||
|
||||
const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, |
||||
const char* name) { |
||||
upb_value v; |
||||
// TODO(haberman): non-extension fields and oneofs.
|
||||
if (upb_strtable_lookup(&s->syms, name, &v)) { |
||||
switch (_upb_DefType_Type(v)) { |
||||
case UPB_DEFTYPE_EXT: { |
||||
const upb_FieldDef* f = _upb_DefType_Unpack(v, UPB_DEFTYPE_EXT); |
||||
return upb_FieldDef_File(f); |
||||
} |
||||
case UPB_DEFTYPE_MSG: { |
||||
const upb_MessageDef* m = _upb_DefType_Unpack(v, UPB_DEFTYPE_MSG); |
||||
return upb_MessageDef_File(m); |
||||
} |
||||
case UPB_DEFTYPE_ENUM: { |
||||
const upb_EnumDef* e = _upb_DefType_Unpack(v, UPB_DEFTYPE_ENUM); |
||||
return upb_EnumDef_File(e); |
||||
} |
||||
case UPB_DEFTYPE_ENUMVAL: { |
||||
const upb_EnumValueDef* ev = |
||||
_upb_DefType_Unpack(v, UPB_DEFTYPE_ENUMVAL); |
||||
return upb_EnumDef_File(upb_EnumValueDef_Enum(ev)); |
||||
} |
||||
case UPB_DEFTYPE_SERVICE: { |
||||
const upb_ServiceDef* service = |
||||
_upb_DefType_Unpack(v, UPB_DEFTYPE_SERVICE); |
||||
return upb_ServiceDef_File(service); |
||||
} |
||||
default: |
||||
UPB_UNREACHABLE(); |
||||
} |
||||
} |
||||
|
||||
const char* last_dot = strrchr(name, '.'); |
||||
if (last_dot) { |
||||
const upb_MessageDef* parent = |
||||
upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name); |
||||
if (parent) { |
||||
const char* shortname = last_dot + 1; |
||||
if (upb_MessageDef_FindByNameWithSize(parent, shortname, |
||||
strlen(shortname), NULL, NULL)) { |
||||
return upb_MessageDef_File(parent); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { |
||||
intptr_t iter = UPB_INTTABLE_BEGIN; |
||||
upb_StringView key; |
||||
upb_value val; |
||||
while (upb_strtable_next2(&s->syms, &key, &val, &iter)) { |
||||
const upb_FileDef* f; |
||||
switch (_upb_DefType_Type(val)) { |
||||
case UPB_DEFTYPE_EXT: |
||||
f = upb_FieldDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_EXT)); |
||||
break; |
||||
case UPB_DEFTYPE_MSG: |
||||
f = upb_MessageDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_MSG)); |
||||
break; |
||||
case UPB_DEFTYPE_ENUM: |
||||
f = upb_EnumDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_ENUM)); |
||||
break; |
||||
case UPB_DEFTYPE_ENUMVAL: |
||||
f = upb_EnumDef_File(upb_EnumValueDef_Enum( |
||||
_upb_DefType_Unpack(val, UPB_DEFTYPE_ENUMVAL))); |
||||
break; |
||||
case UPB_DEFTYPE_SERVICE: |
||||
f = upb_ServiceDef_File(_upb_DefType_Unpack(val, UPB_DEFTYPE_SERVICE)); |
||||
break; |
||||
default: |
||||
UPB_UNREACHABLE(); |
||||
} |
||||
|
||||
if (f == file) upb_strtable_removeiter(&s->syms, &iter); |
||||
} |
||||
} |
||||
|
||||
static const upb_FileDef* _upb_DefPool_AddFile( |
||||
upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, |
||||
const upb_MiniTable_File* layout, upb_Status* status) { |
||||
const upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto); |
||||
|
||||
// Determine whether we already know about this file.
|
||||
{ |
||||
upb_value v; |
||||
if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) { |
||||
upb_Status_SetErrorFormat(status, |
||||
"duplicate file name " UPB_STRINGVIEW_FORMAT, |
||||
UPB_STRINGVIEW_ARGS(name)); |
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
upb_DefBuilder ctx = { |
||||
.symtab = s, |
||||
.layout = layout, |
||||
.msg_count = 0, |
||||
.enum_count = 0, |
||||
.ext_count = 0, |
||||
.status = status, |
||||
.file = NULL, |
||||
.arena = upb_Arena_New(), |
||||
.tmp_arena = upb_Arena_New(), |
||||
}; |
||||
|
||||
if (UPB_SETJMP(ctx.err)) { |
||||
UPB_ASSERT(!upb_Status_IsOk(status)); |
||||
if (ctx.file) { |
||||
remove_filedef(s, ctx.file); |
||||
ctx.file = NULL; |
||||
} |
||||
} else if (!ctx.arena || !ctx.tmp_arena) { |
||||
_upb_DefBuilder_OomErr(&ctx); |
||||
} else { |
||||
_upb_FileDef_Create(&ctx, file_proto); |
||||
upb_strtable_insert(&s->files, name.data, name.size, |
||||
upb_value_constptr(ctx.file), ctx.arena); |
||||
UPB_ASSERT(upb_Status_IsOk(status)); |
||||
upb_Arena_Fuse(s->arena, ctx.arena); |
||||
} |
||||
|
||||
if (ctx.arena) upb_Arena_Free(ctx.arena); |
||||
if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena); |
||||
return ctx.file; |
||||
} |
||||
|
||||
const upb_FileDef* upb_DefPool_AddFile( |
||||
upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, |
||||
upb_Status* status) { |
||||
return _upb_DefPool_AddFile(s, file_proto, NULL, status); |
||||
} |
||||
|
||||
/* Include here since we want most of this file to be stdio-free. */ |
||||
#include <stdio.h> |
||||
|
||||
bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, |
||||
bool rebuild_minitable) { |
||||
/* Since this function should never fail (it would indicate a bug in upb) we
|
||||
* print errors to stderr instead of returning error status to the user. */ |
||||
_upb_DefPool_Init** deps = init->deps; |
||||
google_protobuf_FileDescriptorProto* file; |
||||
upb_Arena* arena; |
||||
upb_Status status; |
||||
|
||||
upb_Status_Clear(&status); |
||||
|
||||
if (upb_DefPool_FindFileByName(s, init->filename)) { |
||||
return true; |
||||
} |
||||
|
||||
arena = upb_Arena_New(); |
||||
|
||||
for (; *deps; deps++) { |
||||
if (!_upb_DefPool_LoadDefInitEx(s, *deps, rebuild_minitable)) goto err; |
||||
} |
||||
|
||||
file = google_protobuf_FileDescriptorProto_parse_ex( |
||||
init->descriptor.data, init->descriptor.size, NULL, |
||||
kUpb_DecodeOption_AliasString, arena); |
||||
s->bytes_loaded += init->descriptor.size; |
||||
|
||||
if (!file) { |
||||
upb_Status_SetErrorFormat( |
||||
&status, |
||||
"Failed to parse compiled-in descriptor for file '%s'. This should " |
||||
"never happen.", |
||||
init->filename); |
||||
goto err; |
||||
} |
||||
|
||||
const upb_MiniTable_File* mt = rebuild_minitable ? NULL : init->layout; |
||||
if (!_upb_DefPool_AddFile(s, file, mt, &status)) { |
||||
goto err; |
||||
} |
||||
|
||||
upb_Arena_Free(arena); |
||||
return true; |
||||
|
||||
err: |
||||
fprintf(stderr, |
||||
"Error loading compiled-in descriptor for file '%s' (this should " |
||||
"never happen): %s\n", |
||||
init->filename, upb_Status_ErrorMessage(&status)); |
||||
upb_Arena_Free(arena); |
||||
return false; |
||||
} |
||||
|
||||
size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) { |
||||
return s->bytes_loaded; |
||||
} |
||||
|
||||
upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; } |
||||
|
||||
const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable( |
||||
const upb_DefPool* s, const upb_MiniTable_Extension* ext) { |
||||
upb_value v; |
||||
bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v); |
||||
UPB_ASSERT(ok); |
||||
return upb_value_getconstptr(v); |
||||
} |
||||
|
||||
const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, |
||||
const upb_MessageDef* m, |
||||
int32_t fieldnum) { |
||||
const upb_MiniTable* l = upb_MessageDef_MiniTable(m); |
||||
const upb_MiniTable_Extension* ext = _upb_extreg_get(s->extreg, l, fieldnum); |
||||
return ext ? _upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL; |
||||
} |
||||
|
||||
const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( |
||||
const upb_DefPool* s) { |
||||
return s->extreg; |
||||
} |
||||
|
||||
const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, |
||||
const upb_MessageDef* m, |
||||
size_t* count) { |
||||
size_t n = 0; |
||||
intptr_t iter = UPB_INTTABLE_BEGIN; |
||||
uintptr_t key; |
||||
upb_value val; |
||||
// This is O(all exts) instead of O(exts for m). If we need this to be
|
||||
// efficient we may need to make extreg into a two-level table, or have a
|
||||
// second per-message index.
|
||||
while (upb_inttable_next2(&s->exts, &key, &val, &iter)) { |
||||
const upb_FieldDef* f = upb_value_getconstptr(val); |
||||
if (upb_FieldDef_ContainingType(f) == m) n++; |
||||
} |
||||
const upb_FieldDef** exts = malloc(n * sizeof(*exts)); |
||||
iter = UPB_INTTABLE_BEGIN; |
||||
size_t i = 0; |
||||
while (upb_inttable_next2(&s->exts, &key, &val, &iter)) { |
||||
const upb_FieldDef* f = upb_value_getconstptr(val); |
||||
if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f; |
||||
} |
||||
*count = n; |
||||
return exts; |
||||
} |
||||
|
||||
bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init) { |
||||
return _upb_DefPool_LoadDefInitEx(s, init, false); |
||||
} |
@ -0,0 +1,143 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_DEF_POOL_H_ |
||||
#define UPB_REFLECTION_DEF_POOL_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/string_view.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
void upb_DefPool_Free(upb_DefPool* s); |
||||
|
||||
upb_DefPool* upb_DefPool_New(void); |
||||
|
||||
const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s, |
||||
const char* sym); |
||||
|
||||
const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize( |
||||
const upb_DefPool* s, const char* sym, size_t len); |
||||
|
||||
const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s, |
||||
const char* sym); |
||||
|
||||
const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s, |
||||
const char* sym); |
||||
|
||||
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s, |
||||
const char* name); |
||||
|
||||
const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, |
||||
const char* name, |
||||
size_t len); |
||||
|
||||
const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( |
||||
const upb_DefPool* s, const char* name, size_t size); |
||||
|
||||
const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, |
||||
const char* sym); |
||||
|
||||
const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s, |
||||
const char* name); |
||||
|
||||
const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize( |
||||
const upb_DefPool* s, const char* name, size_t size); |
||||
|
||||
const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, |
||||
const char* name); |
||||
|
||||
const upb_FileDef* upb_DefPool_AddFile( |
||||
upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto, |
||||
upb_Status* status); |
||||
|
||||
const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s, |
||||
const upb_MessageDef* m, |
||||
int32_t fieldnum); |
||||
|
||||
const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( |
||||
const upb_DefPool* s); |
||||
|
||||
const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, |
||||
const upb_MessageDef* m, |
||||
size_t* count); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
// For generated code only: loads a generated descriptor.
|
||||
typedef struct _upb_DefPool_Init { |
||||
struct _upb_DefPool_Init** deps; // Dependencies of this file.
|
||||
const upb_MiniTable_File* layout; |
||||
const char* filename; |
||||
upb_StringView descriptor; // Serialized descriptor.
|
||||
} _upb_DefPool_Init; |
||||
|
||||
upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s); |
||||
size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s); |
||||
|
||||
bool _upb_DefPool_Contains(const upb_DefPool* s, const char* sym); |
||||
|
||||
upb_ExtensionRegistry* _upb_DefPool_ExtReg(const upb_DefPool* s); |
||||
|
||||
bool _upb_DefPool_Insert(upb_DefPool* s, const char* sym, upb_value v); |
||||
bool _upb_DefPool_Insert2(upb_DefPool* s, const char* sym, size_t size, |
||||
upb_value v); |
||||
|
||||
bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTable_Extension* ext, |
||||
upb_FieldDef* f, upb_Arena* a); |
||||
|
||||
const void* _upb_DefPool_Lookup2(const upb_DefPool* s, const char* sym, |
||||
size_t size, upb_deftype_t type); |
||||
|
||||
bool _upb_DefPool_LookupAny2(const upb_DefPool* s, const char* sym, size_t size, |
||||
upb_value* v); |
||||
|
||||
const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable( |
||||
const upb_DefPool* s, const upb_MiniTable_Extension* ext); |
||||
|
||||
// Should only be directly called by tests. This variant lets us suppress
|
||||
// the use of compiled-in tables, forcing a rebuild of the tables at runtime.
|
||||
bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, |
||||
bool rebuild_minitable); |
||||
|
||||
bool _upb_DefPool_LoadDefInit(upb_DefPool* s, const _upb_DefPool_Init* init); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_DEF_POOL_H_ */ |
@ -0,0 +1,81 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#ifndef UPB_REFLECTION_DEF_TYPE_H_ |
||||
#define UPB_REFLECTION_DEF_TYPE_H_ |
||||
|
||||
#include "upb/internal/table.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
// Inside a symtab we store tagged pointers to specific def types.
|
||||
typedef enum { |
||||
UPB_DEFTYPE_MASK = 7, |
||||
|
||||
// Only inside symtab table.
|
||||
UPB_DEFTYPE_EXT = 0, |
||||
UPB_DEFTYPE_MSG = 1, |
||||
UPB_DEFTYPE_ENUM = 2, |
||||
UPB_DEFTYPE_ENUMVAL = 3, |
||||
UPB_DEFTYPE_SERVICE = 4, |
||||
|
||||
// Only inside message table.
|
||||
UPB_DEFTYPE_FIELD = 0, |
||||
UPB_DEFTYPE_ONEOF = 1, |
||||
UPB_DEFTYPE_FIELD_JSONNAME = 2, |
||||
} upb_deftype_t; |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
// Our 3-bit pointer tagging requires all pointers to be multiples of 8.
|
||||
// The arena will always yield 8-byte-aligned addresses, however we put
|
||||
// the defs into arrays. For each element in the array to be 8-byte-aligned,
|
||||
// the sizes of each def type must also be a multiple of 8.
|
||||
//
|
||||
// If any of these asserts fail, we need to add or remove padding on 32-bit
|
||||
// machines (64-bit machines will have 8-byte alignment already due to
|
||||
// pointers, which all of these structs have).
|
||||
UPB_INLINE void _upb_DefType_CheckPadding(size_t size) { |
||||
UPB_ASSERT((size & UPB_DEFTYPE_MASK) == 0); |
||||
} |
||||
|
||||
upb_deftype_t _upb_DefType_Type(upb_value v); |
||||
|
||||
upb_value _upb_DefType_Pack(const void* ptr, upb_deftype_t type); |
||||
|
||||
const void* _upb_DefType_Unpack(upb_value v, upb_deftype_t type); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_DEF_TYPE_H_ */ |
@ -0,0 +1,247 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/enum_def.h" |
||||
|
||||
#include <stdio.h> |
||||
|
||||
#include "upb/mini_table.h" |
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/enum_value_def.h" |
||||
#include "upb/reflection/file_def.h" |
||||
#include "upb/reflection/message_def.h" |
||||
#include "upb/reflection/mini_descriptor_encode.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_EnumDef { |
||||
const google_protobuf_EnumOptions* opts; |
||||
const upb_MiniTable_Enum* layout; // Only for proto2.
|
||||
const upb_FileDef* file; |
||||
const upb_MessageDef* containing_type; // Could be merged with "file".
|
||||
const char* full_name; |
||||
upb_strtable ntoi; |
||||
upb_inttable iton; |
||||
const upb_EnumValueDef* values; |
||||
int value_count; |
||||
int32_t defaultval; |
||||
bool is_sorted; // Whether all of the values are defined in ascending order.
|
||||
}; |
||||
|
||||
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { |
||||
return (upb_EnumDef*)&e[i]; |
||||
} |
||||
|
||||
// TODO: Maybe implement this on top of a ZCOS instead?
|
||||
void _upb_EnumDef_Debug(const upb_EnumDef* e) { |
||||
fprintf(stderr, "enum %s (%p) {\n", e->full_name, e); |
||||
fprintf(stderr, " value_count: %d\n", e->value_count); |
||||
fprintf(stderr, " default: %d\n", e->defaultval); |
||||
fprintf(stderr, " is_sorted: %d\n", e->is_sorted); |
||||
fprintf(stderr, "}\n"); |
||||
} |
||||
|
||||
const upb_MiniTable_Enum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) { |
||||
return e->layout; |
||||
} |
||||
|
||||
bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) { |
||||
const char* name = upb_EnumValueDef_Name(v); |
||||
const upb_value val = upb_value_constptr(v); |
||||
bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a); |
||||
if (!ok) return false; |
||||
|
||||
// Multiple enumerators can have the same number, first one wins.
|
||||
const int number = upb_EnumValueDef_Number(v); |
||||
if (!upb_inttable_lookup(&e->iton, number, NULL)) { |
||||
return upb_inttable_insert(&e->iton, number, val, a); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
static int cmp_values(const void* a, const void* b) { |
||||
const uint32_t A = upb_EnumValueDef_Number(*(const upb_EnumValueDef**)a); |
||||
const uint32_t B = upb_EnumValueDef_Number(*(const upb_EnumValueDef**)b); |
||||
return (A < B) ? -1 : (A > B); |
||||
} |
||||
|
||||
const char* _upb_EnumDef_MiniDescriptor(const upb_EnumDef* e, upb_Arena* a) { |
||||
if (e->is_sorted) return _upb_MiniDescriptor_EncodeEnum(e, NULL, a); |
||||
|
||||
const upb_EnumValueDef** sorted = (const upb_EnumValueDef**)upb_Arena_Malloc( |
||||
a, e->value_count * sizeof(void*)); |
||||
if (!sorted) return NULL; |
||||
|
||||
for (size_t i = 0; i < e->value_count; i++) { |
||||
sorted[i] = upb_EnumDef_Value(e, i); |
||||
} |
||||
qsort(sorted, e->value_count, sizeof(void*), cmp_values); |
||||
|
||||
return _upb_MiniDescriptor_EncodeEnum(e, sorted, a); |
||||
} |
||||
|
||||
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { |
||||
return e->opts; |
||||
} |
||||
|
||||
bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { |
||||
return e->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } |
||||
|
||||
const char* upb_EnumDef_Name(const upb_EnumDef* e) { |
||||
return _upb_DefBuilder_FullToShort(e->full_name); |
||||
} |
||||
|
||||
const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; } |
||||
|
||||
const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) { |
||||
return e->containing_type; |
||||
} |
||||
|
||||
int32_t upb_EnumDef_Default(const upb_EnumDef* e) { |
||||
UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval)); |
||||
return e->defaultval; |
||||
} |
||||
|
||||
int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } |
||||
|
||||
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, |
||||
const char* name) { |
||||
return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); |
||||
} |
||||
|
||||
const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( |
||||
const upb_EnumDef* e, const char* name, size_t size) { |
||||
upb_value v; |
||||
return upb_strtable_lookup2(&e->ntoi, name, size, &v) |
||||
? upb_value_getconstptr(v) |
||||
: NULL; |
||||
} |
||||
|
||||
const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, |
||||
int32_t num) { |
||||
upb_value v; |
||||
return upb_inttable_lookup(&e->iton, num, &v) ? upb_value_getconstptr(v) |
||||
: NULL; |
||||
} |
||||
|
||||
bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) { |
||||
// We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect
|
||||
// this to be faster (especially for small numbers).
|
||||
return upb_MiniTable_Enum_CheckValue(e->layout, num); |
||||
} |
||||
|
||||
const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { |
||||
UPB_ASSERT(0 <= i && i < e->value_count); |
||||
return _upb_EnumValueDef_At(e->values, i); |
||||
} |
||||
|
||||
static upb_MiniTable_Enum* create_enumlayout(upb_DefBuilder* ctx, |
||||
const upb_EnumDef* e) { |
||||
const char* desc = _upb_EnumDef_MiniDescriptor(e, ctx->tmp_arena); |
||||
if (!desc) |
||||
_upb_DefBuilder_Errf(ctx, "OOM while building enum MiniDescriptor"); |
||||
|
||||
upb_Status status; |
||||
upb_MiniTable_Enum* layout = |
||||
upb_MiniTable_BuildEnum(desc, strlen(desc), ctx->arena, &status); |
||||
if (!layout) |
||||
_upb_DefBuilder_Errf(ctx, "Error building enum MiniTable: %s", status.msg); |
||||
return layout; |
||||
} |
||||
|
||||
static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, |
||||
const google_protobuf_EnumDescriptorProto* enum_proto, |
||||
upb_EnumDef* e) { |
||||
const google_protobuf_EnumValueDescriptorProto* const* values; |
||||
upb_StringView name; |
||||
size_t n; |
||||
|
||||
// Must happen before _upb_DefBuilder_Add()
|
||||
e->file = _upb_DefBuilder_File(ctx); |
||||
|
||||
name = google_protobuf_EnumDescriptorProto_name(enum_proto); |
||||
_upb_DefBuilder_CheckIdentNotFull(ctx, name); |
||||
|
||||
e->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); |
||||
_upb_DefBuilder_Add(ctx, e->full_name, |
||||
_upb_DefType_Pack(e, UPB_DEFTYPE_ENUM)); |
||||
|
||||
values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n); |
||||
|
||||
bool ok = upb_strtable_init(&e->ntoi, n, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
ok = upb_inttable_init(&e->iton, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
e->defaultval = 0; |
||||
e->value_count = n; |
||||
e->values = _upb_EnumValueDefs_New(ctx, prefix, n, values, e, &e->is_sorted); |
||||
|
||||
if (n == 0) { |
||||
_upb_DefBuilder_Errf(ctx, "enums must contain at least one value (%s)", |
||||
e->full_name); |
||||
} |
||||
|
||||
UBP_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); |
||||
|
||||
upb_inttable_compact(&e->iton, ctx->arena); |
||||
|
||||
if (upb_FileDef_Syntax(e->file) == kUpb_Syntax_Proto2) { |
||||
if (ctx->layout) { |
||||
UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count); |
||||
e->layout = ctx->layout->enums[ctx->enum_count++]; |
||||
} else { |
||||
e->layout = create_enumlayout(ctx, e); |
||||
} |
||||
} else { |
||||
e->layout = NULL; |
||||
} |
||||
} |
||||
|
||||
upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_EnumDescriptorProto* const* protos, |
||||
const upb_MessageDef* containing_type) { |
||||
_upb_DefType_CheckPadding(sizeof(upb_EnumDef)); |
||||
|
||||
// If a containing type is defined then get the full name from that.
|
||||
// Otherwise use the package name from the file def.
|
||||
const char* name = containing_type ? upb_MessageDef_FullName(containing_type) |
||||
: _upb_FileDef_RawPackage(ctx->file); |
||||
|
||||
upb_EnumDef* e = _upb_DefBuilder_Alloc(ctx, sizeof(upb_EnumDef) * n); |
||||
for (size_t i = 0; i < n; i++) { |
||||
create_enumdef(ctx, name, protos[i], &e[i]); |
||||
e[i].containing_type = containing_type; |
||||
} |
||||
return e; |
||||
} |
@ -0,0 +1,79 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_ENUM_DEF_H_ |
||||
#define UPB_REFLECTION_ENUM_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); |
||||
const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); |
||||
int32_t upb_EnumDef_Default(const upb_EnumDef* e); |
||||
const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e); |
||||
const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, |
||||
const char* name); |
||||
const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( |
||||
const upb_EnumDef* e, const char* name, size_t size); |
||||
const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, |
||||
int32_t num); |
||||
const char* upb_EnumDef_FullName(const upb_EnumDef* e); |
||||
bool upb_EnumDef_HasOptions(const upb_EnumDef* e); |
||||
const char* upb_EnumDef_Name(const upb_EnumDef* e); |
||||
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e); |
||||
const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i); |
||||
int upb_EnumDef_ValueCount(const upb_EnumDef* e); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i); |
||||
bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); |
||||
const upb_MiniTable_Enum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); |
||||
|
||||
// Builds and returns a mini descriptor, or NULL if OOM.
|
||||
const char* _upb_EnumDef_MiniDescriptor(const upb_EnumDef* e, upb_Arena* a); |
||||
|
||||
// Allocate and initialize an array of |n| enum defs.
|
||||
upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_EnumDescriptorProto* const* protos, |
||||
const upb_MessageDef* containing_type); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_ENUM_DEF_H_ */ |
@ -0,0 +1,123 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/enum_value_def.h" |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/enum_def.h" |
||||
#include "upb/reflection/file_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_EnumValueDef { |
||||
const google_protobuf_EnumValueOptions* opts; |
||||
const upb_EnumDef* parent; |
||||
const char* full_name; |
||||
int32_t number; |
||||
}; |
||||
|
||||
upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i) { |
||||
return (upb_EnumValueDef*)&v[i]; |
||||
} |
||||
|
||||
const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( |
||||
const upb_EnumValueDef* v) { |
||||
return v->opts; |
||||
} |
||||
|
||||
bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v) { |
||||
return v->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v) { |
||||
return v->parent; |
||||
} |
||||
|
||||
const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) { |
||||
return v->full_name; |
||||
} |
||||
|
||||
const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) { |
||||
return _upb_DefBuilder_FullToShort(v->full_name); |
||||
} |
||||
|
||||
int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v) { return v->number; } |
||||
|
||||
uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { |
||||
// Compute index in our parent's array.
|
||||
return v - upb_EnumDef_Value(v->parent, 0); |
||||
} |
||||
|
||||
static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, |
||||
const google_protobuf_EnumValueDescriptorProto* val_proto, |
||||
upb_EnumDef* e, upb_EnumValueDef* v) { |
||||
upb_StringView name = google_protobuf_EnumValueDescriptorProto_name(val_proto); |
||||
|
||||
v->parent = e; // Must happen prior to _upb_DefBuilder_Add()
|
||||
v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); |
||||
v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); |
||||
_upb_DefBuilder_Add(ctx, v->full_name, |
||||
_upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); |
||||
|
||||
UBP_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, |
||||
val_proto); |
||||
|
||||
bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
} |
||||
|
||||
// Allocate and initialize an array of |n| enum value defs owned by |e|.
|
||||
upb_EnumValueDef* _upb_EnumValueDefs_New( |
||||
upb_DefBuilder* ctx, const char* prefix, int n, |
||||
const google_protobuf_EnumValueDescriptorProto* const* protos, upb_EnumDef* e, |
||||
bool* is_sorted) { |
||||
_upb_DefType_CheckPadding(sizeof(upb_EnumValueDef)); |
||||
|
||||
upb_EnumValueDef* v = |
||||
_upb_DefBuilder_Alloc(ctx, sizeof(upb_EnumValueDef) * n); |
||||
|
||||
*is_sorted = true; |
||||
uint32_t previous = 0; |
||||
for (size_t i = 0; i < n; i++) { |
||||
create_enumvaldef(ctx, prefix, protos[i], e, &v[i]); |
||||
|
||||
const uint32_t current = v[i].number; |
||||
if (previous > current) *is_sorted = false; |
||||
previous = current; |
||||
} |
||||
|
||||
if (upb_FileDef_Syntax(ctx->file) == kUpb_Syntax_Proto3 && n > 0 && |
||||
v[0].number != 0) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"for proto3, the first enum value must be zero (%s)", |
||||
upb_EnumDef_FullName(e)); |
||||
} |
||||
|
||||
return v; |
||||
} |
@ -0,0 +1,67 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_ |
||||
#define UPB_REFLECTION_ENUM_VALUE_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v); |
||||
const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v); |
||||
bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v); |
||||
uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v); |
||||
const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); |
||||
int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); |
||||
const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( |
||||
const upb_EnumValueDef* v); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i); |
||||
|
||||
// Allocate and initialize an array of |n| enum value defs owned by |e|.
|
||||
upb_EnumValueDef* _upb_EnumValueDefs_New( |
||||
upb_DefBuilder* ctx, const char* prefix, int n, |
||||
const google_protobuf_EnumValueDescriptorProto* const* protos, upb_EnumDef* e, |
||||
bool* is_sorted); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_ENUM_VALUE_DEF_H_ */ |
@ -0,0 +1,94 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/extension_range.h" |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/field_def.h" |
||||
#include "upb/reflection/message_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_ExtensionRange { |
||||
const google_protobuf_ExtensionRangeOptions* opts; |
||||
int32_t start; |
||||
int32_t end; |
||||
}; |
||||
|
||||
upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i) { |
||||
return (upb_ExtensionRange*)&r[i]; |
||||
} |
||||
|
||||
const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( |
||||
const upb_ExtensionRange* r) { |
||||
return r->opts; |
||||
} |
||||
|
||||
bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) { |
||||
return r->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r) { |
||||
return r->start; |
||||
} |
||||
|
||||
int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r) { return r->end; } |
||||
|
||||
upb_ExtensionRange* _upb_ExtensionRanges_New( |
||||
upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_DescriptorProto_ExtensionRange* const* protos, |
||||
const upb_MessageDef* m) { |
||||
upb_ExtensionRange* r = |
||||
_upb_DefBuilder_Alloc(ctx, sizeof(upb_ExtensionRange) * n); |
||||
|
||||
for (int i = 0; i < n; i++) { |
||||
const int32_t start = |
||||
google_protobuf_DescriptorProto_ExtensionRange_start(protos[i]); |
||||
const int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(protos[i]); |
||||
const int32_t max = |
||||
google_protobuf_MessageOptions_message_set_wire_format(upb_MessageDef_Options(m)) |
||||
? INT32_MAX |
||||
: kUpb_MaxFieldNumber + 1; |
||||
|
||||
// A full validation would also check that each range is disjoint, and that
|
||||
// none of the fields overlap with the extension ranges, but we are just
|
||||
// sanity checking here.
|
||||
if (start < 1 || end <= start || end > max) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"Extension range (%d, %d) is invalid, message=%s\n", |
||||
(int)start, (int)end, upb_MessageDef_FullName(m)); |
||||
} |
||||
|
||||
r[i].start = start; |
||||
r[i].end = end; |
||||
UBP_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, |
||||
ExtensionRangeOptions, protos[i]); |
||||
} |
||||
|
||||
return r; |
||||
} |
@ -0,0 +1,65 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_EXTENSION_RANGE_H_ |
||||
#define UPB_REFLECTION_EXTENSION_RANGE_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* r); |
||||
int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); |
||||
|
||||
bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); |
||||
const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options( |
||||
const upb_ExtensionRange* r); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i); |
||||
|
||||
// Allocate and initialize an array of |n| extension ranges owned by |m|.
|
||||
upb_ExtensionRange* _upb_ExtensionRanges_New( |
||||
upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_DescriptorProto_ExtensionRange* const* protos, |
||||
const upb_MessageDef* m); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_EXTENSION_RANGE_H_ */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,102 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_FIELD_DEF_H_ |
||||
#define UPB_REFLECTION_FIELD_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
// Maximum field number allowed for FieldDefs.
|
||||
// This is an inherent limit of the protobuf wire format.
|
||||
#define kUpb_MaxFieldNumber ((1 << 29) - 1) |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f); |
||||
const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f); |
||||
upb_CType upb_FieldDef_CType(const upb_FieldDef* f); |
||||
const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f); |
||||
const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f); |
||||
const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f); |
||||
const char* upb_FieldDef_FullName(const upb_FieldDef* f); |
||||
bool upb_FieldDef_HasDefault(const upb_FieldDef* f); |
||||
bool upb_FieldDef_HasJsonName(const upb_FieldDef* f); |
||||
bool upb_FieldDef_HasOptions(const upb_FieldDef* f); |
||||
bool upb_FieldDef_HasPresence(const upb_FieldDef* f); |
||||
bool upb_FieldDef_HasSubDef(const upb_FieldDef* f); |
||||
uint32_t upb_FieldDef_Index(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsExtension(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsMap(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsOptional(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsPacked(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsRepeated(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsRequired(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsString(const upb_FieldDef* f); |
||||
bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f); |
||||
const char* upb_FieldDef_JsonName(const upb_FieldDef* f); |
||||
upb_Label upb_FieldDef_Label(const upb_FieldDef* f); |
||||
const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f); |
||||
const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f); |
||||
const char* upb_FieldDef_Name(const upb_FieldDef* f); |
||||
uint32_t upb_FieldDef_Number(const upb_FieldDef* f); |
||||
const google_protobuf_FieldOptions* upb_FieldDef_Options(const upb_FieldDef* f); |
||||
const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f); |
||||
upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i); |
||||
const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable( |
||||
const upb_FieldDef* f); |
||||
bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f); |
||||
|
||||
// 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 char* prefix, |
||||
upb_MessageDef* m, bool is_ext); |
||||
|
||||
void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, |
||||
upb_FieldDef* f); |
||||
|
||||
void _upb_FieldDef_MakeLayout(upb_DefBuilder* ctx, const upb_MessageDef* m); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_FIELD_DEF_H_ */ |
@ -0,0 +1,339 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/file_def.h" |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_pool.h" |
||||
#include "upb/reflection/enum_def.h" |
||||
#include "upb/reflection/field_def.h" |
||||
#include "upb/reflection/message_def.h" |
||||
#include "upb/reflection/service_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_FileDef { |
||||
const google_protobuf_FileOptions* opts; |
||||
const char* name; |
||||
const char* package; |
||||
|
||||
const upb_FileDef** deps; |
||||
const int32_t* public_deps; |
||||
const int32_t* weak_deps; |
||||
const upb_MessageDef* top_lvl_msgs; |
||||
const upb_EnumDef* top_lvl_enums; |
||||
const upb_FieldDef* top_lvl_exts; |
||||
const upb_ServiceDef* services; |
||||
const upb_MiniTable_Extension** ext_layouts; |
||||
const upb_DefPool* symtab; |
||||
|
||||
int dep_count; |
||||
int public_dep_count; |
||||
int weak_dep_count; |
||||
int top_lvl_msg_count; |
||||
int top_lvl_enum_count; |
||||
int top_lvl_ext_count; |
||||
int service_count; |
||||
int ext_count; // All exts in the file.
|
||||
upb_Syntax syntax; |
||||
}; |
||||
|
||||
const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) { |
||||
return f->opts; |
||||
} |
||||
|
||||
bool upb_FileDef_HasOptions(const upb_FileDef* f) { |
||||
return f->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; } |
||||
|
||||
const char* upb_FileDef_Package(const upb_FileDef* f) { |
||||
return f->package ? f->package : ""; |
||||
} |
||||
|
||||
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) { |
||||
return f->top_lvl_msg_count; |
||||
} |
||||
|
||||
int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; } |
||||
|
||||
int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) { |
||||
return f->public_dep_count; |
||||
} |
||||
|
||||
int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { |
||||
return f->weak_dep_count; |
||||
} |
||||
|
||||
const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { |
||||
return f->public_deps; |
||||
} |
||||
|
||||
const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) { |
||||
return f->weak_deps; |
||||
} |
||||
|
||||
int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) { |
||||
return f->top_lvl_enum_count; |
||||
} |
||||
|
||||
int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) { |
||||
return f->top_lvl_ext_count; |
||||
} |
||||
|
||||
int upb_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; } |
||||
|
||||
const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->dep_count); |
||||
return f->deps[i]; |
||||
} |
||||
|
||||
const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->public_dep_count); |
||||
return f->deps[f->public_deps[i]]; |
||||
} |
||||
|
||||
const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->public_dep_count); |
||||
return f->deps[f->weak_deps[i]]; |
||||
} |
||||
|
||||
const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count); |
||||
return _upb_MessageDef_At(f->top_lvl_msgs, i); |
||||
} |
||||
|
||||
const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count); |
||||
return _upb_EnumDef_At(f->top_lvl_enums, i); |
||||
} |
||||
|
||||
const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count); |
||||
return _upb_FieldDef_At(f->top_lvl_exts, i); |
||||
} |
||||
|
||||
const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) { |
||||
UPB_ASSERT(0 <= i && i < f->service_count); |
||||
return _upb_ServiceDef_At(f->services, i); |
||||
} |
||||
|
||||
const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; } |
||||
|
||||
const upb_MiniTable_Extension* _upb_FileDef_ExtensionMiniTable( |
||||
const upb_FileDef* f, int i) { |
||||
return f->ext_layouts[i]; |
||||
} |
||||
|
||||
static char* strviewdup(upb_DefBuilder* ctx, upb_StringView view) { |
||||
char* ret = upb_strdup2(view.data, view.size, _upb_DefBuilder_Arena(ctx)); |
||||
if (!ret) _upb_DefBuilder_OomErr(ctx); |
||||
return ret; |
||||
} |
||||
|
||||
static bool streql_view(upb_StringView view, const char* b) { |
||||
return view.size == strlen(b) && memcmp(view.data, b, view.size) == 0; |
||||
} |
||||
|
||||
static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) { |
||||
size_t n; |
||||
google_protobuf_DescriptorProto_extension(msg_proto, &n); |
||||
int ext_count = n; |
||||
|
||||
const google_protobuf_DescriptorProto* const* nested_msgs = |
||||
google_protobuf_DescriptorProto_nested_type(msg_proto, &n); |
||||
for (size_t i = 0; i < n; i++) { |
||||
ext_count += count_exts_in_msg(nested_msgs[i]); |
||||
} |
||||
|
||||
return ext_count; |
||||
} |
||||
|
||||
// Allocate and initialize one file def, and add it to the context object.
|
||||
void _upb_FileDef_Create(upb_DefBuilder* ctx, |
||||
const google_protobuf_FileDescriptorProto* file_proto) { |
||||
upb_FileDef* file = _upb_DefBuilder_Alloc(ctx, sizeof(upb_FileDef)); |
||||
ctx->file = file; |
||||
|
||||
const google_protobuf_DescriptorProto* const* msgs; |
||||
const google_protobuf_EnumDescriptorProto* const* enums; |
||||
const google_protobuf_FieldDescriptorProto* const* exts; |
||||
const google_protobuf_ServiceDescriptorProto* const* services; |
||||
const upb_StringView* strs; |
||||
const int32_t* public_deps; |
||||
const int32_t* weak_deps; |
||||
size_t i, n; |
||||
|
||||
file->symtab = ctx->symtab; |
||||
|
||||
// Count all extensions in the file, to build a flat array of layouts.
|
||||
google_protobuf_FileDescriptorProto_extension(file_proto, &n); |
||||
int ext_count = n; |
||||
msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); |
||||
for (int i = 0; i < n; i++) { |
||||
ext_count += count_exts_in_msg(msgs[i]); |
||||
} |
||||
file->ext_count = ext_count; |
||||
|
||||
if (ctx->layout) { |
||||
// We are using the ext layouts that were passed in.
|
||||
file->ext_layouts = ctx->layout->exts; |
||||
if (ctx->layout->ext_count != file->ext_count) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"Extension count did not match layout (%d vs %d)", |
||||
ctx->layout->ext_count, file->ext_count); |
||||
} |
||||
} else { |
||||
// We are building ext layouts from scratch.
|
||||
file->ext_layouts = _upb_DefBuilder_Alloc( |
||||
ctx, sizeof(*file->ext_layouts) * file->ext_count); |
||||
upb_MiniTable_Extension* ext = |
||||
_upb_DefBuilder_Alloc(ctx, sizeof(*ext) * file->ext_count); |
||||
for (int i = 0; i < file->ext_count; i++) { |
||||
file->ext_layouts[i] = &ext[i]; |
||||
} |
||||
} |
||||
|
||||
if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) { |
||||
_upb_DefBuilder_Errf(ctx, "File has no name"); |
||||
} |
||||
|
||||
file->name = strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto)); |
||||
|
||||
upb_StringView package = google_protobuf_FileDescriptorProto_package(file_proto); |
||||
if (package.size) { |
||||
_upb_DefBuilder_CheckIdentFull(ctx, package); |
||||
file->package = strviewdup(ctx, package); |
||||
} else { |
||||
file->package = NULL; |
||||
} |
||||
|
||||
if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) { |
||||
upb_StringView syntax = google_protobuf_FileDescriptorProto_syntax(file_proto); |
||||
|
||||
if (streql_view(syntax, "proto2")) { |
||||
file->syntax = kUpb_Syntax_Proto2; |
||||
} else if (streql_view(syntax, "proto3")) { |
||||
file->syntax = kUpb_Syntax_Proto3; |
||||
} else { |
||||
_upb_DefBuilder_Errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", |
||||
UPB_STRINGVIEW_ARGS(syntax)); |
||||
} |
||||
} else { |
||||
file->syntax = kUpb_Syntax_Proto2; |
||||
} |
||||
|
||||
// Read options.
|
||||
UBP_DEF_SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); |
||||
|
||||
// Verify dependencies.
|
||||
strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n); |
||||
file->dep_count = n; |
||||
file->deps = _upb_DefBuilder_Alloc(ctx, sizeof(*file->deps) * n); |
||||
|
||||
for (i = 0; i < n; i++) { |
||||
upb_StringView str = strs[i]; |
||||
file->deps[i] = |
||||
upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size); |
||||
if (!file->deps[i]) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"Depends on file '" UPB_STRINGVIEW_FORMAT |
||||
"', but it has not been loaded", |
||||
UPB_STRINGVIEW_ARGS(str)); |
||||
} |
||||
} |
||||
|
||||
public_deps = google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n); |
||||
file->public_dep_count = n; |
||||
file->public_deps = |
||||
_upb_DefBuilder_Alloc(ctx, sizeof(*file->public_deps) * n); |
||||
int32_t* mutable_public_deps = (int32_t*)file->public_deps; |
||||
for (i = 0; i < n; i++) { |
||||
if (public_deps[i] >= file->dep_count) { |
||||
_upb_DefBuilder_Errf(ctx, "public_dep %d is out of range", |
||||
(int)public_deps[i]); |
||||
} |
||||
mutable_public_deps[i] = public_deps[i]; |
||||
} |
||||
|
||||
weak_deps = google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n); |
||||
file->weak_dep_count = n; |
||||
file->weak_deps = _upb_DefBuilder_Alloc(ctx, sizeof(*file->weak_deps) * n); |
||||
int32_t* mutable_weak_deps = (int32_t*)file->weak_deps; |
||||
for (i = 0; i < n; i++) { |
||||
if (weak_deps[i] >= file->dep_count) { |
||||
_upb_DefBuilder_Errf(ctx, "weak_dep %d is out of range", |
||||
(int)weak_deps[i]); |
||||
} |
||||
mutable_weak_deps[i] = weak_deps[i]; |
||||
} |
||||
|
||||
// Create enums.
|
||||
enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); |
||||
file->top_lvl_enum_count = n; |
||||
file->top_lvl_enums = _upb_EnumDefs_New(ctx, n, enums, NULL); |
||||
|
||||
// Create extensions.
|
||||
exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n); |
||||
file->top_lvl_ext_count = n; |
||||
file->top_lvl_exts = |
||||
_upb_FieldDefs_New(ctx, n, exts, file->package, NULL, true); |
||||
|
||||
// Create messages.
|
||||
msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n); |
||||
file->top_lvl_msg_count = n; |
||||
file->top_lvl_msgs = _upb_MessageDefs_New(ctx, n, msgs, NULL); |
||||
|
||||
// Create services.
|
||||
services = google_protobuf_FileDescriptorProto_service(file_proto, &n); |
||||
file->service_count = n; |
||||
file->services = _upb_ServiceDefs_New(ctx, n, services); |
||||
|
||||
// Now that all names are in the table, build layouts and resolve refs.
|
||||
for (i = 0; i < (size_t)file->top_lvl_ext_count; i++) { |
||||
_upb_FieldDef_Resolve( |
||||
ctx, file->package, |
||||
(upb_FieldDef*)upb_FileDef_TopLevelExtension(file, i)); |
||||
} |
||||
|
||||
for (i = 0; i < (size_t)file->top_lvl_msg_count; i++) { |
||||
upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i); |
||||
_upb_MessageDef_Resolve(ctx, m); |
||||
} |
||||
|
||||
if (file->ext_count) { |
||||
bool ok = _upb_extreg_add(_upb_DefPool_ExtReg(ctx->symtab), |
||||
file->ext_layouts, file->ext_count); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
} |
||||
} |
@ -0,0 +1,89 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_FILE_DEF_H_ |
||||
#define UPB_REFLECTION_FILE_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); |
||||
int upb_FileDef_DependencyCount(const upb_FileDef* f); |
||||
bool upb_FileDef_HasOptions(const upb_FileDef* f); |
||||
const char* upb_FileDef_Name(const upb_FileDef* f); |
||||
const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); |
||||
const char* upb_FileDef_Package(const upb_FileDef* f); |
||||
const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); |
||||
|
||||
const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i); |
||||
int upb_FileDef_PublicDependencyCount(const upb_FileDef* f); |
||||
|
||||
const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i); |
||||
int upb_FileDef_ServiceCount(const upb_FileDef* f); |
||||
|
||||
upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f); |
||||
|
||||
const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i); |
||||
int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f); |
||||
|
||||
const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i); |
||||
int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f); |
||||
|
||||
const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i); |
||||
int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f); |
||||
|
||||
const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i); |
||||
int upb_FileDef_WeakDependencyCount(const upb_FileDef* f); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
const upb_MiniTable_Extension* _upb_FileDef_ExtensionMiniTable( |
||||
const upb_FileDef* f, int i); |
||||
const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f); |
||||
const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f); |
||||
|
||||
// upb_FileDef_Package() returns "" if f->package is NULL, this does not.
|
||||
const char* _upb_FileDef_RawPackage(const upb_FileDef* f); |
||||
|
||||
void _upb_FileDef_Create(upb_DefBuilder* ctx, |
||||
const google_protobuf_FileDescriptorProto* file_proto); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_FILE_DEF_H_ */ |
@ -0,0 +1,106 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#ifndef UPB_REFLECTION_MESSAGE_H_ |
||||
#define UPB_REFLECTION_MESSAGE_H_ |
||||
|
||||
#include "upb/map.h" |
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f); |
||||
|
||||
/* Creates a new message of the given type in the given arena. */ |
||||
upb_Message* upb_Message_New(const upb_MessageDef* m, upb_Arena* a); |
||||
|
||||
/* Returns the value associated with this field. */ |
||||
upb_MessageValue upb_Message_Get(const upb_Message* msg, const upb_FieldDef* f); |
||||
|
||||
/* Returns a mutable pointer to a map, array, or submessage value. If the given
|
||||
* arena is non-NULL this will construct a new object if it was not previously |
||||
* present. May not be called for primitive fields. */ |
||||
upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, |
||||
const upb_FieldDef* f, |
||||
upb_Arena* a); |
||||
|
||||
/* May only be called for fields where upb_FieldDef_HasPresence(f) == true. */ |
||||
bool upb_Message_Has(const upb_Message* msg, const upb_FieldDef* f); |
||||
|
||||
/* Returns the field that is set in the oneof, or NULL if none are set. */ |
||||
const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, |
||||
const upb_OneofDef* o); |
||||
|
||||
/* Sets the given field to the given value. For a msg/array/map/string, the
|
||||
* caller must ensure that the target data outlives |msg| (by living either in |
||||
* the same arena or a different arena that outlives it). |
||||
* |
||||
* Returns false if allocation fails. */ |
||||
bool upb_Message_Set(upb_Message* msg, const upb_FieldDef* f, |
||||
upb_MessageValue val, upb_Arena* a); |
||||
|
||||
/* Clears any field presence and sets the value back to its default. */ |
||||
void upb_Message_ClearField(upb_Message* msg, const upb_FieldDef* f); |
||||
|
||||
/* Clear all data and unknown fields. */ |
||||
void upb_Message_Clear(upb_Message* msg, const upb_MessageDef* m); |
||||
|
||||
/* Iterate over present fields.
|
||||
* |
||||
* size_t iter = kUpb_Message_Begin; |
||||
* const upb_FieldDef *f; |
||||
* upb_MessageValue val; |
||||
* while (upb_Message_Next(msg, m, ext_pool, &f, &val, &iter)) { |
||||
* process_field(f, val); |
||||
* } |
||||
* |
||||
* If ext_pool is NULL, no extensions will be returned. If the given symtab |
||||
* returns extensions that don't match what is in this message, those extensions |
||||
* will be skipped. |
||||
*/ |
||||
|
||||
#define kUpb_Message_Begin -1 |
||||
bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, |
||||
const upb_DefPool* ext_pool, const upb_FieldDef** f, |
||||
upb_MessageValue* val, size_t* iter); |
||||
|
||||
/* Clears all unknown field data from this message and all submessages. */ |
||||
bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, |
||||
int maxdepth); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_MESSAGE_H_ */ |
@ -0,0 +1,37 @@ |
||||
// Copyright (c) 2009-2021, Google LLC
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google LLC nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef UPB_REFLECTION_MESSAGE_HPP_ |
||||
#define UPB_REFLECTION_MESSAGE_HPP_ |
||||
|
||||
#include "upb/reflection/message.h" |
||||
|
||||
namespace upb { |
||||
|
||||
typedef upb_MessageValue MessageValue; |
||||
|
||||
} // namespace upb
|
||||
|
||||
#endif // UPB_REFLECTION_MESSAGE_HPP_
|
@ -0,0 +1,485 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/message_def.h" |
||||
|
||||
#include "upb/mini_table.h" |
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/enum_def.h" |
||||
#include "upb/reflection/extension_range.h" |
||||
#include "upb/reflection/field_def.h" |
||||
#include "upb/reflection/file_def.h" |
||||
#include "upb/reflection/oneof_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_MessageDef { |
||||
const google_protobuf_MessageOptions* opts; |
||||
const upb_MiniTable* layout; |
||||
const upb_FileDef* file; |
||||
const upb_MessageDef* containing_type; |
||||
const char* full_name; |
||||
|
||||
// Tables for looking up fields by number and name.
|
||||
upb_inttable itof; |
||||
upb_strtable ntof; |
||||
|
||||
/* All nested defs.
|
||||
* MEM: We could save some space here by putting nested defs in a contiguous |
||||
* region and calculating counts from offsets or vice-versa. */ |
||||
const upb_FieldDef* fields; |
||||
const upb_OneofDef* oneofs; |
||||
const upb_ExtensionRange* ext_ranges; |
||||
const upb_MessageDef* nested_msgs; |
||||
const upb_EnumDef* nested_enums; |
||||
const upb_FieldDef* nested_exts; |
||||
int field_count; |
||||
int real_oneof_count; |
||||
int oneof_count; |
||||
int ext_range_count; |
||||
int nested_msg_count; |
||||
int nested_enum_count; |
||||
int nested_ext_count; |
||||
bool in_message_set; |
||||
upb_WellKnown well_known_type; |
||||
#if UINTPTR_MAX == 0xffffffff |
||||
uint32_t padding; // Increase size to a multiple of 8.
|
||||
#endif |
||||
}; |
||||
|
||||
static void assign_msg_wellknowntype(upb_MessageDef* m) { |
||||
const char* name = upb_MessageDef_FullName(m); |
||||
if (name == NULL) { |
||||
m->well_known_type = kUpb_WellKnown_Unspecified; |
||||
return; |
||||
} |
||||
if (!strcmp(name, "google.protobuf.Any")) { |
||||
m->well_known_type = kUpb_WellKnown_Any; |
||||
} else if (!strcmp(name, "google.protobuf.FieldMask")) { |
||||
m->well_known_type = kUpb_WellKnown_FieldMask; |
||||
} else if (!strcmp(name, "google.protobuf.Duration")) { |
||||
m->well_known_type = kUpb_WellKnown_Duration; |
||||
} else if (!strcmp(name, "google.protobuf.Timestamp")) { |
||||
m->well_known_type = kUpb_WellKnown_Timestamp; |
||||
} else if (!strcmp(name, "google.protobuf.DoubleValue")) { |
||||
m->well_known_type = kUpb_WellKnown_DoubleValue; |
||||
} else if (!strcmp(name, "google.protobuf.FloatValue")) { |
||||
m->well_known_type = kUpb_WellKnown_FloatValue; |
||||
} else if (!strcmp(name, "google.protobuf.Int64Value")) { |
||||
m->well_known_type = kUpb_WellKnown_Int64Value; |
||||
} else if (!strcmp(name, "google.protobuf.UInt64Value")) { |
||||
m->well_known_type = kUpb_WellKnown_UInt64Value; |
||||
} else if (!strcmp(name, "google.protobuf.Int32Value")) { |
||||
m->well_known_type = kUpb_WellKnown_Int32Value; |
||||
} else if (!strcmp(name, "google.protobuf.UInt32Value")) { |
||||
m->well_known_type = kUpb_WellKnown_UInt32Value; |
||||
} else if (!strcmp(name, "google.protobuf.BoolValue")) { |
||||
m->well_known_type = kUpb_WellKnown_BoolValue; |
||||
} else if (!strcmp(name, "google.protobuf.StringValue")) { |
||||
m->well_known_type = kUpb_WellKnown_StringValue; |
||||
} else if (!strcmp(name, "google.protobuf.BytesValue")) { |
||||
m->well_known_type = kUpb_WellKnown_BytesValue; |
||||
} else if (!strcmp(name, "google.protobuf.Value")) { |
||||
m->well_known_type = kUpb_WellKnown_Value; |
||||
} else if (!strcmp(name, "google.protobuf.ListValue")) { |
||||
m->well_known_type = kUpb_WellKnown_ListValue; |
||||
} else if (!strcmp(name, "google.protobuf.Struct")) { |
||||
m->well_known_type = kUpb_WellKnown_Struct; |
||||
} else { |
||||
m->well_known_type = kUpb_WellKnown_Unspecified; |
||||
} |
||||
} |
||||
|
||||
upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i) { |
||||
return (upb_MessageDef*)&m[i]; |
||||
} |
||||
|
||||
const google_protobuf_MessageOptions* upb_MessageDef_Options( |
||||
const upb_MessageDef* m) { |
||||
return m->opts; |
||||
} |
||||
|
||||
bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { |
||||
return m->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const char* upb_MessageDef_FullName(const upb_MessageDef* m) { |
||||
return m->full_name; |
||||
} |
||||
|
||||
const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) { |
||||
return m->file; |
||||
} |
||||
|
||||
const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) { |
||||
return m->containing_type; |
||||
} |
||||
|
||||
const char* upb_MessageDef_Name(const upb_MessageDef* m) { |
||||
return _upb_DefBuilder_FullToShort(m->full_name); |
||||
} |
||||
|
||||
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, |
||||
uint32_t i) { |
||||
upb_value val; |
||||
return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val) |
||||
: NULL; |
||||
} |
||||
|
||||
const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( |
||||
const upb_MessageDef* m, const char* name, size_t size) { |
||||
upb_value val; |
||||
|
||||
if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { |
||||
return NULL; |
||||
} |
||||
|
||||
return _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); |
||||
} |
||||
|
||||
const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( |
||||
const upb_MessageDef* m, const char* name, size_t size) { |
||||
upb_value val; |
||||
|
||||
if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { |
||||
return NULL; |
||||
} |
||||
|
||||
return _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); |
||||
} |
||||
|
||||
bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t len, |
||||
upb_value v, upb_Arena* a) { |
||||
return upb_strtable_insert(&m->ntof, name, len, v, a); |
||||
} |
||||
|
||||
bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, |
||||
const char* name, size_t len, |
||||
const upb_FieldDef** out_f, |
||||
const upb_OneofDef** out_o) { |
||||
upb_value val; |
||||
|
||||
if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) { |
||||
return false; |
||||
} |
||||
|
||||
const upb_FieldDef* f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); |
||||
const upb_OneofDef* o = _upb_DefType_Unpack(val, UPB_DEFTYPE_ONEOF); |
||||
if (out_f) *out_f = f; |
||||
if (out_o) *out_o = o; |
||||
return f || o; /* False if this was a JSON name. */ |
||||
} |
||||
|
||||
const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( |
||||
const upb_MessageDef* m, const char* name, size_t size) { |
||||
upb_value val; |
||||
const upb_FieldDef* f; |
||||
|
||||
if (!upb_strtable_lookup2(&m->ntof, name, size, &val)) { |
||||
return NULL; |
||||
} |
||||
|
||||
f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD); |
||||
if (!f) f = _upb_DefType_Unpack(val, UPB_DEFTYPE_FIELD_JSONNAME); |
||||
|
||||
return f; |
||||
} |
||||
|
||||
int upb_MessageDef_numfields(const upb_MessageDef* m) { return m->field_count; } |
||||
|
||||
int upb_MessageDef_numoneofs(const upb_MessageDef* m) { return m->oneof_count; } |
||||
|
||||
int upb_MessageDef_numrealoneofs(const upb_MessageDef* m) { |
||||
return m->real_oneof_count; |
||||
} |
||||
|
||||
int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) { |
||||
return m->ext_range_count; |
||||
} |
||||
|
||||
int upb_MessageDef_FieldCount(const upb_MessageDef* m) { |
||||
return m->field_count; |
||||
} |
||||
|
||||
int upb_MessageDef_OneofCount(const upb_MessageDef* m) { |
||||
return m->oneof_count; |
||||
} |
||||
|
||||
int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) { |
||||
return m->nested_msg_count; |
||||
} |
||||
|
||||
int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) { |
||||
return m->nested_enum_count; |
||||
} |
||||
|
||||
int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) { |
||||
return m->nested_ext_count; |
||||
} |
||||
|
||||
int upb_MessageDef_realoneofcount(const upb_MessageDef* m) { |
||||
return m->real_oneof_count; |
||||
} |
||||
|
||||
const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) { |
||||
return m->layout; |
||||
} |
||||
|
||||
const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, |
||||
int i) { |
||||
UPB_ASSERT(0 <= i && i < m->ext_range_count); |
||||
return _upb_ExtensionRange_At(m->ext_ranges, i); |
||||
} |
||||
|
||||
const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) { |
||||
UPB_ASSERT(0 <= i && i < m->field_count); |
||||
return _upb_FieldDef_At(m->fields, i); |
||||
} |
||||
|
||||
const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) { |
||||
UPB_ASSERT(0 <= i && i < m->oneof_count); |
||||
return _upb_OneofDef_At(m->oneofs, i); |
||||
} |
||||
|
||||
const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, |
||||
int i) { |
||||
UPB_ASSERT(0 <= i && i < m->nested_msg_count); |
||||
return &m->nested_msgs[i]; |
||||
} |
||||
|
||||
const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) { |
||||
UPB_ASSERT(0 <= i && i < m->nested_enum_count); |
||||
return _upb_EnumDef_At(m->nested_enums, i); |
||||
} |
||||
|
||||
const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, |
||||
int i) { |
||||
UPB_ASSERT(0 <= i && i < m->nested_ext_count); |
||||
return _upb_FieldDef_At(m->nested_exts, i); |
||||
} |
||||
|
||||
upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) { |
||||
return m->well_known_type; |
||||
} |
||||
|
||||
bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m) { |
||||
return m->in_message_set; |
||||
} |
||||
|
||||
const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, |
||||
const char* name) { |
||||
return upb_MessageDef_FindFieldByNameWithSize(m, name, strlen(name)); |
||||
} |
||||
|
||||
const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, |
||||
const char* name) { |
||||
return upb_MessageDef_FindOneofByNameWithSize(m, name, strlen(name)); |
||||
} |
||||
|
||||
bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m) { |
||||
return google_protobuf_MessageOptions_map_entry(upb_MessageDef_Options(m)); |
||||
} |
||||
|
||||
bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m) { |
||||
return google_protobuf_MessageOptions_message_set_wire_format( |
||||
upb_MessageDef_Options(m)); |
||||
} |
||||
|
||||
void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m) { |
||||
for (int i = 0; i < upb_MessageDef_FieldCount(m); i++) { |
||||
upb_FieldDef* f = (upb_FieldDef*)upb_MessageDef_Field(m, i); |
||||
_upb_FieldDef_Resolve(ctx, upb_MessageDef_FullName(m), f); |
||||
} |
||||
|
||||
m->in_message_set = false; |
||||
for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) { |
||||
upb_FieldDef* ext = (upb_FieldDef*)upb_MessageDef_NestedExtension(m, i); |
||||
_upb_FieldDef_Resolve(ctx, upb_MessageDef_FullName(m), ext); |
||||
if (upb_FieldDef_Type(ext) == kUpb_FieldType_Message && |
||||
upb_FieldDef_Label(ext) == kUpb_Label_Optional && |
||||
upb_FieldDef_MessageSubDef(ext) == m && |
||||
google_protobuf_MessageOptions_message_set_wire_format( |
||||
upb_MessageDef_Options(upb_FieldDef_ContainingType(ext)))) { |
||||
m->in_message_set = true; |
||||
} |
||||
} |
||||
|
||||
if (!ctx->layout) _upb_FieldDef_MakeLayout(ctx, m); |
||||
|
||||
for (int i = 0; i < upb_MessageDef_NestedMessageCount(m); i++) { |
||||
upb_MessageDef* n = (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i); |
||||
_upb_MessageDef_Resolve(ctx, n); |
||||
} |
||||
} |
||||
|
||||
void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, |
||||
const upb_FieldDef* f) { |
||||
const int32_t field_number = upb_FieldDef_Number(f); |
||||
|
||||
if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) { |
||||
_upb_DefBuilder_Errf(ctx, "invalid field number (%u)", field_number); |
||||
} |
||||
|
||||
const char* json_name = upb_FieldDef_JsonName(f); |
||||
const char* shortname = upb_FieldDef_Name(f); |
||||
const size_t shortnamelen = strlen(shortname); |
||||
|
||||
upb_value v = upb_value_constptr(f); |
||||
|
||||
upb_value existing_v; |
||||
if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) { |
||||
_upb_DefBuilder_Errf(ctx, "duplicate field name (%s)", shortname); |
||||
} |
||||
|
||||
const upb_value field_v = _upb_DefType_Pack(f, UPB_DEFTYPE_FIELD); |
||||
bool ok = |
||||
_upb_MessageDef_Insert(m, shortname, shortnamelen, field_v, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
if (strcmp(shortname, json_name) != 0) { |
||||
if (upb_strtable_lookup(&m->ntof, json_name, &v)) { |
||||
_upb_DefBuilder_Errf(ctx, "duplicate json_name (%s)", json_name); |
||||
} |
||||
|
||||
const size_t json_size = strlen(json_name); |
||||
const upb_value json_v = _upb_DefType_Pack(f, UPB_DEFTYPE_FIELD_JSONNAME); |
||||
ok = _upb_MessageDef_Insert(m, json_name, json_size, json_v, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
} |
||||
|
||||
if (upb_inttable_lookup(&m->itof, field_number, NULL)) { |
||||
_upb_DefBuilder_Errf(ctx, "duplicate field number (%u)", field_number); |
||||
} |
||||
|
||||
ok = upb_inttable_insert(&m->itof, field_number, v, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
} |
||||
|
||||
static void msgdef_create_nested(upb_DefBuilder* ctx, |
||||
const google_protobuf_DescriptorProto* msg_proto, |
||||
upb_MessageDef* m) { |
||||
size_t n; |
||||
|
||||
const google_protobuf_EnumDescriptorProto* const* enums = |
||||
google_protobuf_DescriptorProto_enum_type(msg_proto, &n); |
||||
m->nested_enum_count = n; |
||||
m->nested_enums = _upb_EnumDefs_New(ctx, n, enums, m); |
||||
|
||||
const google_protobuf_FieldDescriptorProto* const* exts = |
||||
google_protobuf_DescriptorProto_extension(msg_proto, &n); |
||||
m->nested_ext_count = n; |
||||
m->nested_exts = _upb_FieldDefs_New(ctx, n, exts, m->full_name, m, true); |
||||
|
||||
const google_protobuf_DescriptorProto* const* msgs = |
||||
google_protobuf_DescriptorProto_nested_type(msg_proto, &n); |
||||
m->nested_msg_count = n; |
||||
m->nested_msgs = _upb_MessageDefs_New(ctx, n, msgs, m); |
||||
} |
||||
|
||||
static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, |
||||
const google_protobuf_DescriptorProto* msg_proto, |
||||
const upb_MessageDef* containing_type, |
||||
const upb_MessageDef* _m) { |
||||
upb_MessageDef* m = (upb_MessageDef*)_m; |
||||
const google_protobuf_OneofDescriptorProto* const* oneofs; |
||||
const google_protobuf_FieldDescriptorProto* const* fields; |
||||
const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges; |
||||
size_t n_oneof, n_field, n_ext_range; |
||||
upb_StringView name; |
||||
|
||||
// Must happen before _upb_DefBuilder_Add()
|
||||
m->file = _upb_DefBuilder_File(ctx); |
||||
|
||||
m->containing_type = containing_type; |
||||
|
||||
name = google_protobuf_DescriptorProto_name(msg_proto); |
||||
_upb_DefBuilder_CheckIdentNotFull(ctx, name); |
||||
|
||||
m->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); |
||||
_upb_DefBuilder_Add(ctx, m->full_name, _upb_DefType_Pack(m, UPB_DEFTYPE_MSG)); |
||||
|
||||
oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof); |
||||
fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field); |
||||
ext_ranges = |
||||
google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range); |
||||
|
||||
bool ok = upb_inttable_init(&m->itof, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
ok = upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
if (ctx->layout) { |
||||
/* create_fielddef() below depends on this being set. */ |
||||
UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count); |
||||
m->layout = ctx->layout->msgs[ctx->msg_count++]; |
||||
UPB_ASSERT(n_field == m->layout->field_count); |
||||
} else { |
||||
/* Allocate now (to allow cross-linking), populate later. */ |
||||
m->layout = _upb_DefBuilder_Alloc( |
||||
ctx, sizeof(*m->layout) + sizeof(_upb_FastTable_Entry)); |
||||
} |
||||
|
||||
UBP_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); |
||||
|
||||
m->oneof_count = n_oneof; |
||||
m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m); |
||||
|
||||
m->field_count = n_field; |
||||
m->fields = _upb_FieldDefs_New(ctx, n_field, fields, m->full_name, m, false); |
||||
|
||||
m->ext_range_count = n_ext_range; |
||||
m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, m); |
||||
|
||||
const size_t synthetic_count = _upb_OneofDefs_Finalize(ctx, m); |
||||
m->real_oneof_count = m->oneof_count - synthetic_count; |
||||
|
||||
assign_msg_wellknowntype(m); |
||||
upb_inttable_compact(&m->itof, ctx->arena); |
||||
msgdef_create_nested(ctx, msg_proto, m); |
||||
} |
||||
|
||||
// Allocate and initialize an array of |n| message defs.
|
||||
upb_MessageDef* _upb_MessageDefs_New( |
||||
upb_DefBuilder* ctx, int n, const google_protobuf_DescriptorProto* const* protos, |
||||
const upb_MessageDef* containing_type) { |
||||
_upb_DefType_CheckPadding(sizeof(upb_MessageDef)); |
||||
|
||||
const char* name = containing_type ? containing_type->full_name |
||||
: _upb_FileDef_RawPackage(ctx->file); |
||||
upb_MessageDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MessageDef) * n); |
||||
for (int i = 0; i < n; i++) { |
||||
create_msgdef(ctx, name, protos[i], containing_type, &m[i]); |
||||
} |
||||
return m; |
||||
} |
@ -0,0 +1,173 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_MESSAGE_DEF_H_ |
||||
#define UPB_REFLECTION_MESSAGE_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
// Well-known field tag numbers for map-entry messages.
|
||||
#define kUpb_MapEntry_KeyFieldNumber 1 |
||||
#define kUpb_MapEntry_ValueFieldNumber 2 |
||||
|
||||
// Well-known field tag numbers for Any messages.
|
||||
#define kUpb_Any_TypeFieldNumber 1 |
||||
#define kUpb_Any_ValueFieldNumber 2 |
||||
|
||||
// Well-known field tag numbers for duration messages.
|
||||
#define kUpb_Duration_SecondsFieldNumber 1 |
||||
#define kUpb_Duration_NanosFieldNumber 2 |
||||
|
||||
// Well-known field tag numbers for timestamp messages.
|
||||
#define kUpb_Timestamp_SecondsFieldNumber 1 |
||||
#define kUpb_Timestamp_NanosFieldNumber 2 |
||||
|
||||
// All the different kind of well known type messages. For simplicity of check,
|
||||
// number wrappers and string wrappers are grouped together. Make sure the
|
||||
// order and number of these groups are not changed.
|
||||
typedef enum { |
||||
kUpb_WellKnown_Unspecified, |
||||
kUpb_WellKnown_Any, |
||||
kUpb_WellKnown_FieldMask, |
||||
kUpb_WellKnown_Duration, |
||||
kUpb_WellKnown_Timestamp, |
||||
|
||||
// number wrappers
|
||||
kUpb_WellKnown_DoubleValue, |
||||
kUpb_WellKnown_FloatValue, |
||||
kUpb_WellKnown_Int64Value, |
||||
kUpb_WellKnown_UInt64Value, |
||||
kUpb_WellKnown_Int32Value, |
||||
kUpb_WellKnown_UInt32Value, |
||||
|
||||
// string wrappers
|
||||
kUpb_WellKnown_StringValue, |
||||
kUpb_WellKnown_BytesValue, |
||||
kUpb_WellKnown_BoolValue, |
||||
kUpb_WellKnown_Value, |
||||
kUpb_WellKnown_ListValue, |
||||
kUpb_WellKnown_Struct, |
||||
} upb_WellKnown; |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m); |
||||
|
||||
const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m, |
||||
int i); |
||||
int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m); |
||||
|
||||
const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i); |
||||
int upb_MessageDef_FieldCount(const upb_MessageDef* m); |
||||
|
||||
const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m); |
||||
|
||||
// Returns a field by either JSON name or regular proto name.
|
||||
const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize( |
||||
const upb_MessageDef* m, const char* name, size_t size); |
||||
UPB_INLINE const upb_FieldDef* upb_MessageDef_FindByJsonName( |
||||
const upb_MessageDef* m, const char* name) { |
||||
return upb_MessageDef_FindByJsonNameWithSize(m, name, strlen(name)); |
||||
} |
||||
|
||||
// Lookup of either field or oneof by name. Returns whether either was found.
|
||||
// If the return is true, then the found def will be set, and the non-found
|
||||
// one set to NULL.
|
||||
bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m, |
||||
const char* name, size_t size, |
||||
const upb_FieldDef** f, |
||||
const upb_OneofDef** o); |
||||
UPB_INLINE bool upb_MessageDef_FindByName(const upb_MessageDef* m, |
||||
const char* name, |
||||
const upb_FieldDef** f, |
||||
const upb_OneofDef** o) { |
||||
return upb_MessageDef_FindByNameWithSize(m, name, strlen(name), f, o); |
||||
} |
||||
|
||||
const upb_FieldDef* upb_MessageDef_FindFieldByName(const upb_MessageDef* m, |
||||
const char* name); |
||||
const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize( |
||||
const upb_MessageDef* m, const char* name, size_t size); |
||||
const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m, |
||||
uint32_t i); |
||||
const upb_OneofDef* upb_MessageDef_FindOneofByName(const upb_MessageDef* m, |
||||
const char* name); |
||||
const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize( |
||||
const upb_MessageDef* m, const char* name, size_t size); |
||||
const char* upb_MessageDef_FullName(const upb_MessageDef* m); |
||||
bool upb_MessageDef_HasOptions(const upb_MessageDef* m); |
||||
bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m); |
||||
bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m); |
||||
const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m); |
||||
const char* upb_MessageDef_Name(const upb_MessageDef* m); |
||||
|
||||
const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i); |
||||
const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m, |
||||
int i); |
||||
const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m, |
||||
int i); |
||||
|
||||
int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m); |
||||
int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m); |
||||
int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m); |
||||
|
||||
const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i); |
||||
int upb_MessageDef_OneofCount(const upb_MessageDef* m); |
||||
|
||||
const google_protobuf_MessageOptions* upb_MessageDef_Options(const upb_MessageDef* m); |
||||
upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m); |
||||
upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_MessageDef* _upb_MessageDef_At(const upb_MessageDef* m, int i); |
||||
bool _upb_MessageDef_InMessageSet(const upb_MessageDef* m); |
||||
bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t size, |
||||
upb_value v, upb_Arena* a); |
||||
void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, |
||||
const upb_FieldDef* f); |
||||
void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m); |
||||
|
||||
// Allocate and initialize an array of |n| message defs.
|
||||
upb_MessageDef* _upb_MessageDefs_New( |
||||
upb_DefBuilder* ctx, int n, const google_protobuf_DescriptorProto* const* protos, |
||||
const upb_MessageDef* containing_type); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_MESSAGE_DEF_H_ */ |
@ -0,0 +1,123 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/method_def.h" |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/service_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_MethodDef { |
||||
const google_protobuf_MethodOptions* opts; |
||||
upb_ServiceDef* service; |
||||
const char* full_name; |
||||
const upb_MessageDef* input_type; |
||||
const upb_MessageDef* output_type; |
||||
int index; |
||||
bool client_streaming; |
||||
bool server_streaming; |
||||
}; |
||||
|
||||
upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i) { |
||||
return (upb_MethodDef*)&m[i]; |
||||
} |
||||
|
||||
const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) { |
||||
return m->service; |
||||
} |
||||
|
||||
const google_protobuf_MethodOptions* upb_MethodDef_Options(const upb_MethodDef* m) { |
||||
return m->opts; |
||||
} |
||||
|
||||
bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { |
||||
return m->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const char* upb_MethodDef_FullName(const upb_MethodDef* m) { |
||||
return m->full_name; |
||||
} |
||||
|
||||
const char* upb_MethodDef_Name(const upb_MethodDef* m) { |
||||
return _upb_DefBuilder_FullToShort(m->full_name); |
||||
} |
||||
|
||||
int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; } |
||||
|
||||
const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) { |
||||
return m->input_type; |
||||
} |
||||
|
||||
const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) { |
||||
return m->output_type; |
||||
} |
||||
|
||||
bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) { |
||||
return m->client_streaming; |
||||
} |
||||
|
||||
bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { |
||||
return m->server_streaming; |
||||
} |
||||
|
||||
static void create_method(upb_DefBuilder* ctx, |
||||
const google_protobuf_MethodDescriptorProto* method_proto, |
||||
upb_ServiceDef* s, upb_MethodDef* m) { |
||||
upb_StringView name = google_protobuf_MethodDescriptorProto_name(method_proto); |
||||
|
||||
m->service = s; |
||||
m->full_name = |
||||
_upb_DefBuilder_MakeFullName(ctx, upb_ServiceDef_FullName(s), name); |
||||
m->client_streaming = |
||||
google_protobuf_MethodDescriptorProto_client_streaming(method_proto); |
||||
m->server_streaming = |
||||
google_protobuf_MethodDescriptorProto_server_streaming(method_proto); |
||||
m->input_type = _upb_DefBuilder_Resolve( |
||||
ctx, m->full_name, m->full_name, |
||||
google_protobuf_MethodDescriptorProto_input_type(method_proto), UPB_DEFTYPE_MSG); |
||||
m->output_type = _upb_DefBuilder_Resolve( |
||||
ctx, m->full_name, m->full_name, |
||||
google_protobuf_MethodDescriptorProto_output_type(method_proto), UPB_DEFTYPE_MSG); |
||||
|
||||
UBP_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, |
||||
method_proto); |
||||
} |
||||
|
||||
// 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, upb_ServiceDef* s) { |
||||
upb_MethodDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MethodDef) * n); |
||||
for (int i = 0; i < n; i++) { |
||||
create_method(ctx, protos[i], s, &m[i]); |
||||
m[i].index = i; |
||||
} |
||||
return m; |
||||
} |
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_METHOD_DEF_H_ |
||||
#define UPB_REFLECTION_METHOD_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m); |
||||
const char* upb_MethodDef_FullName(const upb_MethodDef* m); |
||||
bool upb_MethodDef_HasOptions(const upb_MethodDef* m); |
||||
int upb_MethodDef_Index(const upb_MethodDef* m); |
||||
const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); |
||||
const char* upb_MethodDef_Name(const upb_MethodDef* m); |
||||
const google_protobuf_MethodOptions* upb_MethodDef_Options(const upb_MethodDef* m); |
||||
const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); |
||||
bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); |
||||
const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i); |
||||
|
||||
// Allocate and initialize an array of |n| method defs owned by |s|.
|
||||
upb_MethodDef* _upb_MethodDefs_New( |
||||
upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_MethodDescriptorProto* const* protos, upb_ServiceDef* s); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_METHOD_DEF_H_ */ |
@ -0,0 +1,206 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/oneof_def.h" |
||||
|
||||
#include <ctype.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "upb/mini_table.h" |
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/field_def.h" |
||||
#include "upb/reflection/message_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_OneofDef { |
||||
const google_protobuf_OneofOptions* opts; |
||||
const upb_MessageDef* parent; |
||||
const char* full_name; |
||||
int field_count; |
||||
bool synthetic; |
||||
const upb_FieldDef** fields; |
||||
upb_strtable ntof; // lookup a field by name
|
||||
upb_inttable itof; // lookup a field by number (index)
|
||||
#if UINTPTR_MAX == 0xffffffff |
||||
uint32_t padding; // Increase size to a multiple of 8.
|
||||
#endif |
||||
}; |
||||
|
||||
upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i) { |
||||
return (upb_OneofDef*)&o[i]; |
||||
} |
||||
|
||||
const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o) { |
||||
return o->opts; |
||||
} |
||||
|
||||
bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { |
||||
return o->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const char* upb_OneofDef_FullName(const upb_OneofDef* o) { |
||||
return o->full_name; |
||||
} |
||||
|
||||
const char* upb_OneofDef_Name(const upb_OneofDef* o) { |
||||
return _upb_DefBuilder_FullToShort(o->full_name); |
||||
} |
||||
|
||||
const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) { |
||||
return o->parent; |
||||
} |
||||
|
||||
int upb_OneofDef_FieldCount(const upb_OneofDef* o) { return o->field_count; } |
||||
|
||||
const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i) { |
||||
UPB_ASSERT(i < o->field_count); |
||||
return o->fields[i]; |
||||
} |
||||
|
||||
int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; } |
||||
|
||||
uint32_t upb_OneofDef_Index(const upb_OneofDef* o) { |
||||
// Compute index in our parent's array.
|
||||
return o - upb_MessageDef_Oneof(o->parent, 0); |
||||
} |
||||
|
||||
bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; } |
||||
|
||||
const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, |
||||
const char* name, |
||||
size_t size) { |
||||
upb_value val; |
||||
return upb_strtable_lookup2(&o->ntof, name, size, &val) |
||||
? upb_value_getptr(val) |
||||
: NULL; |
||||
} |
||||
|
||||
const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, |
||||
const char* name) { |
||||
return upb_OneofDef_LookupNameWithSize(o, name, strlen(name)); |
||||
} |
||||
|
||||
const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, |
||||
uint32_t num) { |
||||
upb_value val; |
||||
return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val) |
||||
: NULL; |
||||
} |
||||
|
||||
bool _upb_OneofDef_Insert(upb_OneofDef* o, const upb_FieldDef* f, |
||||
const char* name, size_t size, upb_Arena* a) { |
||||
o->field_count++; |
||||
if (_upb_FieldDef_IsProto3Optional(f)) o->synthetic = true; |
||||
|
||||
const int number = upb_FieldDef_Number(f); |
||||
const upb_value v = upb_value_constptr(f); |
||||
return upb_inttable_insert(&o->itof, number, v, a) && |
||||
upb_strtable_insert(&o->ntof, name, size, v, a); |
||||
} |
||||
|
||||
// Returns the synthetic count.
|
||||
size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m) { |
||||
int synthetic_count = 0; |
||||
|
||||
for (int i = 0; i < upb_MessageDef_OneofCount(m); i++) { |
||||
upb_OneofDef* o = (upb_OneofDef*)upb_MessageDef_Oneof(m, i); |
||||
|
||||
if (o->synthetic && o->field_count != 1) { |
||||
_upb_DefBuilder_Errf(ctx, |
||||
"Synthetic oneofs must have one field, not %d: %s", |
||||
o->field_count, upb_OneofDef_Name(o)); |
||||
} |
||||
|
||||
if (o->synthetic) { |
||||
synthetic_count++; |
||||
} else if (synthetic_count != 0) { |
||||
_upb_DefBuilder_Errf( |
||||
ctx, "Synthetic oneofs must be after all other oneofs: %s", |
||||
upb_OneofDef_Name(o)); |
||||
} |
||||
|
||||
o->fields = |
||||
_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef*) * o->field_count); |
||||
o->field_count = 0; |
||||
} |
||||
|
||||
for (int i = 0; i < upb_MessageDef_FieldCount(m); i++) { |
||||
const upb_FieldDef* f = upb_MessageDef_Field(m, i); |
||||
upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f); |
||||
if (o) { |
||||
o->fields[o->field_count++] = f; |
||||
} |
||||
} |
||||
|
||||
return synthetic_count; |
||||
} |
||||
|
||||
static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, |
||||
const google_protobuf_OneofDescriptorProto* oneof_proto, |
||||
const upb_OneofDef* _o) { |
||||
upb_OneofDef* o = (upb_OneofDef*)_o; |
||||
upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto); |
||||
|
||||
o->parent = m; |
||||
o->full_name = |
||||
_upb_DefBuilder_MakeFullName(ctx, upb_MessageDef_FullName(m), name); |
||||
o->field_count = 0; |
||||
o->synthetic = false; |
||||
|
||||
UBP_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); |
||||
|
||||
if (upb_MessageDef_FindByNameWithSize(m, name.data, name.size, NULL, NULL)) { |
||||
_upb_DefBuilder_Errf(ctx, "duplicate oneof name (%s)", o->full_name); |
||||
} |
||||
|
||||
upb_value v = _upb_DefType_Pack(o, UPB_DEFTYPE_ONEOF); |
||||
bool ok = _upb_MessageDef_Insert(m, name.data, name.size, v, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
ok = upb_inttable_init(&o->itof, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
|
||||
ok = upb_strtable_init(&o->ntof, 4, ctx->arena); |
||||
if (!ok) _upb_DefBuilder_OomErr(ctx); |
||||
} |
||||
|
||||
// Allocate and initialize an array of |n| oneof defs.
|
||||
upb_OneofDef* _upb_OneofDefs_New( |
||||
upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_OneofDescriptorProto* const* protos, upb_MessageDef* m) { |
||||
_upb_DefType_CheckPadding(sizeof(upb_OneofDef)); |
||||
|
||||
upb_OneofDef* o = _upb_DefBuilder_Alloc(ctx, sizeof(upb_OneofDef) * n); |
||||
for (int i = 0; i < n; i++) { |
||||
create_oneofdef(ctx, m, protos[i], &o[i]); |
||||
} |
||||
return o; |
||||
} |
@ -0,0 +1,79 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_ONEOF_DEF_H_ |
||||
#define UPB_REFLECTION_ONEOF_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o); |
||||
const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i); |
||||
int upb_OneofDef_FieldCount(const upb_OneofDef* o); |
||||
const char* upb_OneofDef_FullName(const upb_OneofDef* o); |
||||
bool upb_OneofDef_HasOptions(const upb_OneofDef* o); |
||||
uint32_t upb_OneofDef_Index(const upb_OneofDef* o); |
||||
bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o); |
||||
const upb_FieldDef* upb_OneofDef_LookupName(const upb_OneofDef* o, |
||||
const char* name); |
||||
const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o, |
||||
const char* name, |
||||
size_t size); |
||||
const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, |
||||
uint32_t num); |
||||
const char* upb_OneofDef_Name(const upb_OneofDef* o); |
||||
int upb_OneofDef_numfields(const upb_OneofDef* o); |
||||
const google_protobuf_OneofOptions* upb_OneofDef_Options(const upb_OneofDef* o); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i); |
||||
bool _upb_OneofDef_Insert(upb_OneofDef* o, const upb_FieldDef* f, |
||||
const char* name, size_t size, upb_Arena* a); |
||||
|
||||
// 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, upb_MessageDef* m); |
||||
|
||||
size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_ONEOF_DEF_H_ */ |
@ -0,0 +1,129 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
#include "upb/reflection/service_def.h" |
||||
|
||||
#include "upb/reflection/def_builder.h" |
||||
#include "upb/reflection/def_type.h" |
||||
#include "upb/reflection/file_def.h" |
||||
#include "upb/reflection/method_def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
struct upb_ServiceDef { |
||||
const google_protobuf_ServiceOptions* opts; |
||||
const upb_FileDef* file; |
||||
const char* full_name; |
||||
upb_MethodDef* methods; |
||||
int method_count; |
||||
int index; |
||||
}; |
||||
|
||||
upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) { |
||||
return (upb_ServiceDef*)&s[index]; |
||||
} |
||||
|
||||
const google_protobuf_ServiceOptions* upb_ServiceDef_Options(const upb_ServiceDef* s) { |
||||
return s->opts; |
||||
} |
||||
|
||||
bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { |
||||
return s->opts != (void*)kUpbDefOptDefault; |
||||
} |
||||
|
||||
const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { |
||||
return s->full_name; |
||||
} |
||||
|
||||
const char* upb_ServiceDef_Name(const upb_ServiceDef* s) { |
||||
return _upb_DefBuilder_FullToShort(s->full_name); |
||||
} |
||||
|
||||
int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; } |
||||
|
||||
const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) { |
||||
return s->file; |
||||
} |
||||
|
||||
int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) { |
||||
return s->method_count; |
||||
} |
||||
|
||||
const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) { |
||||
return (i < 0 || i >= s->method_count) ? NULL |
||||
: _upb_MethodDef_At(s->methods, i); |
||||
} |
||||
|
||||
const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, |
||||
const char* name) { |
||||
for (int i = 0; i < s->method_count; i++) { |
||||
const upb_MethodDef* m = _upb_MethodDef_At(s->methods, i); |
||||
if (strcmp(name, upb_MethodDef_Name(m)) == 0) { |
||||
return m; |
||||
} |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
static void create_service(upb_DefBuilder* ctx, |
||||
const google_protobuf_ServiceDescriptorProto* svc_proto, |
||||
upb_ServiceDef* s) { |
||||
upb_StringView name; |
||||
size_t n; |
||||
|
||||
// Must happen before _upb_DefBuilder_Add()
|
||||
s->file = _upb_DefBuilder_File(ctx); |
||||
|
||||
name = google_protobuf_ServiceDescriptorProto_name(svc_proto); |
||||
_upb_DefBuilder_CheckIdentNotFull(ctx, name); |
||||
const char* package = _upb_FileDef_RawPackage(s->file); |
||||
s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name); |
||||
_upb_DefBuilder_Add(ctx, s->full_name, |
||||
_upb_DefType_Pack(s, UPB_DEFTYPE_SERVICE)); |
||||
|
||||
const google_protobuf_MethodDescriptorProto* const* methods = |
||||
google_protobuf_ServiceDescriptorProto_method(svc_proto, &n); |
||||
s->method_count = n; |
||||
s->methods = _upb_MethodDefs_New(ctx, n, methods, s); |
||||
|
||||
UBP_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, |
||||
svc_proto); |
||||
} |
||||
|
||||
upb_ServiceDef* _upb_ServiceDefs_New( |
||||
upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_ServiceDescriptorProto* const* protos) { |
||||
_upb_DefType_CheckPadding(sizeof(upb_ServiceDef)); |
||||
|
||||
upb_ServiceDef* s = _upb_DefBuilder_Alloc(ctx, sizeof(upb_ServiceDef) * n); |
||||
for (int i = 0; i < n; i++) { |
||||
create_service(ctx, protos[i], &s[i]); |
||||
s[i].index = i; |
||||
} |
||||
return s; |
||||
} |
@ -0,0 +1,68 @@ |
||||
/*
|
||||
* Copyright (c) 2009-2021, Google LLC |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are met: |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* * Neither the name of Google LLC nor the |
||||
* names of its contributors may be used to endorse or promote products |
||||
* derived from this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT, |
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
|
||||
// IWYU pragma: private, include "third_party/upb/upb/reflection/def.h"
|
||||
|
||||
#ifndef UPB_REFLECTION_SERVICE_DEF_H_ |
||||
#define UPB_REFLECTION_SERVICE_DEF_H_ |
||||
|
||||
#include "upb/reflection/common.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port_def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s); |
||||
const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, |
||||
const char* name); |
||||
const char* upb_ServiceDef_FullName(const upb_ServiceDef* s); |
||||
bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s); |
||||
int upb_ServiceDef_Index(const upb_ServiceDef* s); |
||||
const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i); |
||||
int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); |
||||
const char* upb_ServiceDef_Name(const upb_ServiceDef* s); |
||||
const google_protobuf_ServiceOptions* upb_ServiceDef_Options(const upb_ServiceDef* s); |
||||
|
||||
// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE /////////////////////////
|
||||
|
||||
upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int i); |
||||
|
||||
// Allocate and initialize an array of |n| service defs.
|
||||
upb_ServiceDef* _upb_ServiceDefs_New( |
||||
upb_DefBuilder* ctx, int n, |
||||
const google_protobuf_ServiceDescriptorProto* const* protos); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* UPB_REFLECTION_SERVICE_DEF_H_ */ |
Loading…
Reference in new issue