option cpp_opmessage = true; // Turn on generation of OpTypedMessage sub-classes for all top-level messages
option cpp_component = framework;

// See modules/hardcore/cpp.conf for details on custom types used in this file

/**
 * Opera Status message.
 *
 * The intended use case is code performing an operation on behalf of a caller
 * in another component, and simply returning the status will automagically
 * cause a message of this type to be sent to the caller on the local channel.
 *
 * Example:
 * @msc
 * Component1, Component2;
 * Component1 -> Component2
 *    [label="1. SendMessage(SomeMessage::Create())",
 *     url="\ref OpComponent::SendMessage()"];
 * Component2 => Component2
 *    [label="2. ProcessMessage()",
 *     url="\ref OpComponent::ProcessMessage()"];
 * Component2 -> Component1
 *    [label="3. SendMessage(OpStatusMessage)",
 *     url="\ref OpComponent::SendMessage()"];
 * Component1 -> Component1
 *    [label="4. ProcessMessage()",
 *     url="\ref OpComponent::ProcessMessage()"];
 * @endmsc
 *
 * -# Component \#1: sends some message to a remote component:
 *    @code
 *        OpComponent* remote_component = ...;
 *        remote_component->SendMessage(OpDoSomethingMessage::Create());
 *    @endcode
 * -# Component \#2: receives the message an handles it in
 *    OpComponent::ProcessMessage() or OpMessageListener::ProcessMessage(). If
 *    the handling method returns an error status on handling the message:
 *    @code
 *         switch (message->GetType()) {
 *         case OpDoSomethingMessage::Type:
 *            return OpStatus::ERR;
 *         ...
 *         }
 *    @endcode
 * -# Component \#2: ... sends an OpStatusMessage with the return OP_STATUS
 *    value back to the sender.
 * -# Component \#1: can then receive this message and handle it in its
 *    OpMessageListener::ProcessMessage():
 *    @code
 *        switch (message->GetType()) {
 *        case OpStatusMessage::Type:
 *        {
 *            OP_STATUS status = OpStatusMessage::Cast(message)->GetStatus();
 *            // do something sensible with the status
 *            ...
 *            break;
 *        }
 *    @endcode
 *
 *
 */
message Status
{
    /// Numeric OP_STATUS code.
    required int32 status = 1 [cpp_exttype = OP_STATUS];
}

/**
 * Simple text message.
 *
 * Used for testing.
 */
message Text
{
    required string text = 1;
}

/**
 * Simple numeric message.
 *
 * Used for testing.
 */
message Number
{
	required int64 number = 1;
}

/**
 * Component manager response message.
 *
 * Used internally by the component infrastructure layer.
 */
message ComponentManagerResponse
{
    /// Request identifier.
    required int32 request = 1;
    /// Type of component requested.
    required int32 componentType = 2 [cpp_exttype = OpComponentType];
}

/**
 * Component request message.
 *
 * Used internally by the component infrastructure layer. Sent from component
 * where a request was made to the initial component manager.
 */
message ComponentRequest
{
    /// Type of component requested.
    required int32 componentType = 1 [cpp_exttype = OpComponentType];
}

/**
 * Message signalling that an entity is present and ready to communicate.
 *
 * Used internally by the component infrastructure layer.
 *
 * Do NOT use this message for any other purpose. Channels receiving this
 * message will update their internal records based on its origin, and
 * this may break communication paths.
 */
message PeerConnected
{
}

/**
 * Message to notify that a channel's peer is pending.
 * This message is sent to the OpChannel that is returned by
 * OpComponent::RequestComponent(). The initial OpComponentManager sends it
 * after passing the corresponding OpComponentRequestMessage to the platform
 * (see OpComponentPlatform::RequestPeer()). The source address of the message
 * is the address of the destination OpComponentManager which will host the
 * requested OpComponent.
 * @see OpComponent::RequestComponent()
 *
 * On requesting a new OpComponent, the returned root channel to the new
 * component doesn't have a destination address yet. This message sets the
 * destination address of the root channel to the address of the destination
 * OpComponentManager. If the OpComponentManager dies before creating the
 * requested component, the root channel will be notified by an
 * OpPeerDisconnectedMessage.
 *
 * @note It is possible that the destination OpComponentManager creates the
 *       requested OpComponent before this message is sent. In that case the
 *       root channel will receive an OpPeerConnectedMessage before receiving
 *       this message and this message will be ignored.
 *
 * This message is used internally by the component framework.
 *
 * Do NOT use this message for any other purpose. Channels receiving this
 * message will update their internal records based on its origin, and
 * this may break communication paths.
 */
message PeerPending
{
}

/**
 * Message to notify the disconnection of a channel.
 *
 * Used internally by the component infrastructure layer.
 *
 * Do NOT use this message for any other purpose. Channels receiving this
 * message will update their internal records based on its origin, and
 * this may break communication paths.
 */
message PeerDisconnected
{
}

/**
 * OpMessageAddress representation.
 *
 * - Component Manager ID: SetManager(), GetManager().
 * - Manager-local component ID: SetComponent(), GetComponent().
 * - Component-local channel ID: SetChannel(), GetChannel().
 */
message MessageAddress
{
	option cpp_opmessage = false;

	required int32 manager = 1;
	required int32 component = 2;
	required int32 channel = 3;
}
