> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arupa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Protobuf

> 了解 Protobuf 如何定义内核和插件之间的契约。

作为插件开发者，您可以使用 Protobuf 作为插件与Arupa 内核之间的契约。
该契约定义了插件接收的消息、它返回的响应以及它可以向内核请求的共享操作。
生成的代码将该契约转换为插件使用的类型化 SDK。
您可以在此 SDK 之上实现您的功能。您无需自行编写二进制序列化、进程通信或 WASM 主机绑定。

Protobuf 仅定义了边界；您的插件仍然拥有功能逻辑以及不跨越该边界的数据结构。

## 哪些内容跨越插件边界

该协议承载两种通信：

```文本 theme={null}
内核 ── 生命周期上下文、请求和事件 ──▶ 您的插件
内核 ◀─ 用于共享功能的类型化请求 ─── 您的插件
```

当内核启动您的插件时，它会将自身的配置提供给插件，
并允许插件声明其提供的资源。之后，传入的请求和事件在到达您的处理程序之前会被转换为 Protobuf 消息。

您的处理程序返回 Protobuf 消息，内核会将这些消息转换回相应的应用程序响应。

如果您的功能需要内核拥有的功能，请使用生成的宿主绑定。
内核执行操作并将类型化结果返回给您的插件。
将特定于功能的状态和行为保留在您的插件中；
使用宿主边界来处理共享的应用程序功能。

## 选择后端

根据您要使用的语言和运行时选择后端。两个后端都使用相同的 Protobuf 合约，但它们的实现要求有所不同。

### gRPC

您可以使用任何支持 Protobuf 和 gRPC 的语言来实现 gRPC 插件。

该插件作为独立进程运行，并通过 Protobuf 合约的 gRPC 形式与内核通信。

使用您所用语言的 Protobuf 和 gRPC 工具来生成或实现合约类型，然后在插件清单中设置 `Type: grpc`。

### WASM

Arupa 目前支持使用 Go 语言开发 WASM 插件。使用为 Arupa Protobuf 合约生成的 Go SDK，
并将插件编译为 WASM。WASM 集成基于 [`knqyf263/go-plugin`](https://github.com/knqyf263/go-plugin)，该插件生成 Go 接口，并将原始 WASM 通信隐藏在 SDK 之后。
定义或使用 Protobuf 合约，生成 Go 绑定，实现生成的插件接口，并将实现编译为 WASM 模块。在插件清单中设置`Type: wasm`。

传输方式会改变，但消息类型及其含义保持不变。
选择与插件清单中的 `Type` 匹配的 SDK 和构建流程。

## 使用生成的 SDK

`.proto` 模式是插件合约的真实来源。由此生成的 SDK包含插件在编译期间使用的消息类型和后端绑定。

将生成的文件视为构建产物。不要手动编辑它们。
如果您需要使用新添加的消息或字段，请从匹配的模式重新生成 SDK 并重新构建您的插件。

在 `info.yaml` 文件中将 `ContractVersion` 设置为您的插件使用的协议版本。

该版本必须受加载该软件包的内核支持。
清单版本和生成的 SDK 应始终保持同步更新。
使用生成的 SDK 可为您的插件带来以下优势：

* 类型化的请求和响应值；
* 与内核一致的序列化；
* 由运行时处理特定于传输的通信；以及
* 插件契约的统一编程模型。

## 保持插件兼容性

当您使用较新的契约时，请记住 Protobuf 使用编号（而不仅仅是名称）来标识字段：

* 保持现有字段编号与其原始含义一致；
* 不要重用已删除字段的编号；
* 添加新字段时使用新的编号；以及
* 允许您的插件在更改向后兼容时忽略不需要的字段。

请勿更改插件本地假设中现有字段的含义或类型。如果更改不向后兼容，
请使用相应的新合约版本并基于该版本重新构建插件。

## 典型开发流程

开发插件时，请使用以下工作流程：

1. 选择 WASM 或 gRPC，并使用匹配的生成 SDK。
2. 使用 SDK 类型实现插件合约和功能逻辑。
3. 在注册期间声明插件提供的资源。
4. 当您的功能需要内核拥有的功能时，请使用主机绑定。
5. 在插件清单中设置匹配的 `ContractVersion`。
6. 构建并打包插件，然后使用支持该合约版本的内核加载它。

界限很简单：您的插件实现行为，而 Protobuf 和生成的 SDK 承载类型化数据。
