# Metadata System

Nodes in a Model can contain Metadata stored in a PropertyBag and accessed via the GetMetadata method:

```cpp
        /// <summary> Get this object's metadata object. </summary>
        ///
        /// <returns> A reference to the PropertyBag containing the metadata for this object. </returns>
        utilities::PropertyBag& GetMetadata() { return _metadata; }
```

So adding Metadata to a node is simple, you can just do this:

```cpp
node->GetMetadata().SetEntry("foo", std::string("bar"));

```

The PropertyBag class stores the values in a Variant so it can remember 
primitive types like int, float, double and string.  These values are serialized with the Model and therefore persist with the model.

The python interface for getting and setting metadata on a node is 
string based.  All values are converted to strings as follows:

```python
    node.SetMetadataValue("foo", "bar")
    v = node.GetMetadataValue("foo");
```

Metadata on nodes that are `refined` away is lost during refinement, but metadata on nodes that are `Compilable` is included in the emitted module.   The "C" interface that is emitted for accessing metadata is also string based, as follows:

```c
char* mfcc_GetMetadata(char* key);
```

The strongly typed C++ ModelWrapper that is also generated in the header contains the following helper function
you can use to access the metadata using std::string.

```cpp
    const char* GetMetadata(const char* name) const
    {
        return mfcc_GetMetadata((char*)name.c_str());
    }
```

The `key` parameter is the same metadata name provided in the SetEntry method, so you can write this test code in C++:

```cpp
    ModelWrapper model;
    const char* value = model.GetMetadata("foo");
```

Notice then that you can only access metadata that has a unique key.  If multiple nodes contain the same metadata key, you will only be able to access the first instance via this interface.

And this is also available to the Python wrapper generated by `wrap.py` as follows:

```python
    model = module.ModelWrapper()
    value = model.GetMetadata("foo")
```


