Implementation:Alibaba MNN Protobuf Reflection H
Metadata
| Attribute | Value |
|---|---|
| Implementation File | 3rd_party/protobuf/src/google/protobuf/reflection.h
|
| Line Count | 568 |
| Domains | Serialization, Reflection |
| Key Class | Reflection
|
| Created | 2026-02-10 |
| Knowledge Sources | Repo, Doc |
Overview
Message reflection interface for dynamic field access. Provides runtime introspection and mutation of protobuf message fields without compile-time knowledge of the message type.
Usage note: Vendored dependency used internally by MNN for parsing protobuf-based model formats. Not directly imported by end users.
Description
The Reflection class enables dynamic access to message fields by FieldDescriptor rather than by generated accessor methods. This powers:
- Dynamic field get/set -- Type-specific getter/setter methods for all protobuf scalar types (
GetInt32,SetString, etc.) as well as message, enum, and repeated field accessors. - Repeated field manipulation --
AddInt32,AddMessage,FieldSize,RemoveLast, etc. - Unknown field access --
GetUnknownFields,MutableUnknownFields. - Oneof support --
HasOneof,GetOneofFieldDescriptor,ClearOneof. - Message operations --
SwapFields,ListFields,HasField,ClearField.
Reflection is essential for text format printing, JSON conversion, and any code that processes messages generically (e.g., merging, diffing, or transforming arbitrary protobuf messages).
Usage
#include "google/protobuf/reflection.h"
Accessed via Message::GetReflection(). Used by TextFormat, MessageDifferencer, and generic protobuf utilities.
Code Reference
class PROTOBUF_EXPORT Reflection {
public:
virtual ~Reflection();
// Field presence.
virtual bool HasField(const Message& message,
const FieldDescriptor* field) const = 0;
virtual int FieldSize(const Message& message,
const FieldDescriptor* field) const = 0;
virtual void ClearField(Message* message,
const FieldDescriptor* field) const = 0;
// Scalar field access (one per type).
virtual int32_t GetInt32(const Message& message,
const FieldDescriptor* field) const = 0;
virtual void SetInt32(Message* message,
const FieldDescriptor* field,
int32_t value) const = 0;
// ... GetInt64, GetUInt32, GetFloat, GetDouble, GetBool, GetString, etc.
// Sub-message access.
virtual const Message& GetMessage(const Message& message,
const FieldDescriptor* field) const = 0;
virtual Message* MutableMessage(Message* message,
const FieldDescriptor* field) const = 0;
// Repeated field access.
virtual int32_t GetRepeatedInt32(const Message& message,
const FieldDescriptor* field,
int index) const = 0;
virtual void AddInt32(Message* message,
const FieldDescriptor* field,
int32_t value) const = 0;
// Unknown fields.
virtual const UnknownFieldSet& GetUnknownFields(
const Message& message) const = 0;
virtual UnknownFieldSet* MutableUnknownFields(
Message* message) const = 0;
// List all set fields.
virtual void ListFields(
const Message& message,
std::vector<const FieldDescriptor*>* output) const = 0;
};
I/O Contract
| Direction | Type | Description |
|---|---|---|
| Input | Message + FieldDescriptor |
Message instance and field metadata for reflection operations |
| Output | Typed values | Field values retrieved dynamically by descriptor |
| Mutation | Message* |
In-place modification of message fields |
Usage Examples
// Dynamically read all fields from a message
const Reflection* refl = msg.GetReflection();
const Descriptor* desc = msg.GetDescriptor();
for (int i = 0; i < desc->field_count(); ++i) {
const FieldDescriptor* field = desc->field(i);
if (refl->HasField(msg, field)) {
if (field->type() == FieldDescriptor::TYPE_INT32) {
int32_t val = refl->GetInt32(msg, field);
}
}
}