Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Alibaba MNN Protobuf Reflection H

From Leeroopedia


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);
    }
  }
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment