A MoonBit protobuf ecosystem lab for dynamic schema validation, compatibility testing, and AI code verification.
.proto -> Schema Doctor -> compatibility check -> dynamic binary/JSON runtime
-> MoonBit codegen -> generated-code compile -> Markdown/JUnit/CI evidencemoon add 123123213weqw/moon_protoimport {
"123123213weqw/moon_proto" @proto,
}fn main {
let encoded = @proto.encode_varint_u64(300UL)
println(encoded.length()) // 2
}git clone https://github.com/123123213weqw/moon_proto.git
cd moon_proto
# 检查 AI/人工生成的 schema
python3 scripts/moon_proto_lab.py doctor examples/ai/good_order.proto
# 完成 doctor、inspect、codegen、生成代码编译并输出报告
python3 scripts/moon_proto_lab.py verify \
examples/ai/good_order.proto \
--report generated/verify_report.md \
--junit-out generated/verify_report.xml
# 检查 old/new schema 是否兼容
python3 scripts/moon_proto_lab.py compat \
examples/ai/good_order.proto \
examples/ai/good_order_v2.proto \
--report generated/compat_report.mdbash scripts/release_gate.sh| 能力 | 当前实现 |
|---|---|
| Wire/runtime | varint、zig-zag、fixed32/64、length-delimited、unknown-field skip |
| Schema | proto3 message、enum、optional/repeated、map、oneof、reserved、nested type、常见声明容错 |
| 动态消息 | descriptor-driven scalar、repeated、packed、enum、nested、map、oneof 二进制编解码 |
| Protobuf JSON | enum name、64-bit integer、base64、Unicode、lowerCamel、map key normalization、严格数字语法 |
| Schema Doctor | 字段号/名称冲突、enum 规则、map 约束、reserved 复用等稳定诊断 |
| 兼容性检查 | old/new .proto 与 FileDescriptorSet 的破坏性变更检查 |
| Codegen | MoonBit struct、enum、descriptor、动态 runtime helper,并执行真实 moon check |
| 工程证据 | Python/Go oracle、建模的 conformance-lite 用例、官方接口契约检查、Markdown/JSON/JUnit 报告 |
| Registry adapter | descriptor registry、release policy、文件/HTTP/profile/GitHub Contents 适配验证 |
syntax = "proto3";
message Order {
reserved 7;
reserved "legacy_note";
uint64 id = 1;
string duplicate = 1;
bytes legacy_note = 7;
map<bytes, string> invalid_labels = 8;
}python3 scripts/moon_proto_lab.py doctor examples/ai/bad_order.protoschema invalid
issues: 6
message.Order.field.1: duplicate field number
message.Order.field.invalid_labels.key: invalid map key type
message.Order.field.legacy_note.number: field uses reserved number
message.Order.field.legacy_note.name: field uses reserved namelet desc = @proto.MessageDescriptor::{
name: "User",
fields: [
@proto.FieldDescriptor::{
name: "id",
typ: @proto.UInt64Type,
number: 1,
label: @proto.Singular,
},
@proto.FieldDescriptor::{
name: "name",
typ: @proto.StringType,
number: 2,
label: @proto.Singular,
},
],
}
let msg = @proto.message_value([
@proto.message_field("id", @proto.UInt64Value(150UL)),
@proto.message_field("name", @proto.StringValue("Alice")),
])
let encoded = @proto.encode_message(desc, msg)moon fmt --check
moon info
moon package --list
moon check --deny-warn
moon build
moon test --deny-warn
moon test --target all
moon coverage analyze -p 123123213weqw/moon_proto -- -f summary
tests/codegen/compile_generated.shpub(all) enum DecodeMessageResult {
DecodeMessageOk(MessageValue, Int)
DecodeMessageErr(DecodeError)
} derive(Eq, Debug)pub(all) enum DecodeU64FixedResult {
U64FixedOk(UInt64, Int)
U64FixedErr(DecodeError)
} derive(Eq, Debug)pub(all) enum EncodeMessageResult {
EncodeMessageOk(Bytes)
EncodeMessageErr(DecodeError)
} derive(Eq, Debug)pub(all) struct EnumDescriptor {
name : String
values : Array[EnumValueDescriptor]
allow_alias : Bool
} derive(Eq, Debug)pub(all) struct FieldDescriptor {
name : String
typ : ScalarType
number : Int
label : FieldLabel
} derive(Eq, Debug)pub(all) enum JsonDecodeResult {
JsonDecodeOk(MessageValue)
JsonDecodeErr(DecodeError)
} derive(Eq, Debug)pub(all) struct MessageDescriptor {
name : String
fields : Array[FieldDescriptor]
} derive(Eq, Debug)pub(all) struct ProtoFile {
syntax : String
package_name : String
messages : Array[MessageDescriptor]
enums : Array[EnumDescriptor]
message_reservations : Array[ReservedDescriptor]
enum_reservations : Array[ReservedDescriptor]
} derive(Eq, Debug)pub(all) enum ProtoValue {
UInt64Value(UInt64)
Int64Value(Int64)
FloatValue(Float)
DoubleValue(Double)
BoolValue(Bool)
StringValue(String)
BytesValue(Bytes)
NestedMessageValue(MessageValue)
MapEntryValue(MessageValue)
} derive(Eq, Debug)pub(all) struct ReservedDescriptor {
owner : String
numbers : Array[ReservedNumberRange]
names : Array[String]
} derive(Eq, Debug)pub(all) enum ScalarType {
DoubleType
FloatType
Int32Type
Int64Type
UInt32Type
UInt64Type
SInt32Type
SInt64Type
Fixed32Type
Fixed64Type
SFixed32Type
SFixed64Type
BoolType
StringType
BytesType
EnumType(String)
NamedType(String)
MapType(ScalarType, ScalarType)
} derive(Eq, Debug)pub(all) enum SchemaValidationResult {
SchemaValid
SchemaInvalid(Array[SchemaIssue])
} derive(Eq, Debug)fn base64_encode(input : Bytes) -> Stringfn decode_message_with_descriptors(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], input : Bytes, offset? : Int) -> DecodeMessageResultfn decode_zigzag_i64(value : UInt64) -> Int64fn encode_bool_field(field_number : Int, value : Bool) -> Bytesfn encode_bytes_field(field_number : Int, value : Bytes) -> Bytesfn encode_fixed32(value : UInt) -> Bytesfn encode_fixed64(value : UInt64) -> Bytesfn encode_length_delimited(payload : Bytes) -> Bytesfn encode_message_with_descriptors(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], value : MessageValue) -> EncodeMessageResultfn encode_sint64_field(field_number : Int, value : Int64) -> Bytesfn encode_string(value : String) -> Bytesfn encode_string_field(field_number : Int, value : String) -> Bytesfn encode_uint64_field(field_number : Int, value : UInt64) -> Bytesfn encode_varint_u64(value : UInt64) -> Bytesfn encode_varint_uint(value : UInt) -> Bytesfn encode_zigzag_i64(value : Int64) -> UInt64fn encode_zigzag_int(value : Int) -> UIntfn is_valid_field_number(number : Int) -> Boolfn json_escape_string(value : String) -> Stringfn json_to_message_with_descriptors(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], input : String) -> JsonDecodeResultfn json_to_message_with_schema(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], enum_descriptors : Array[EnumDescriptor], input : String) -> JsonDecodeResultfn message_to_json_lower_camel_with_descriptors(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], value : MessageValue) -> JsonEncodeResultfn message_to_json_lower_camel_with_schema(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], enum_descriptors : Array[EnumDescriptor], value : MessageValue) -> JsonEncodeResultfn message_to_json_with_descriptors(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], value : MessageValue) -> JsonEncodeResultfn message_to_json_with_schema(desc : MessageDescriptor, descriptors : Array[MessageDescriptor], enum_descriptors : Array[EnumDescriptor], value : MessageValue) -> JsonEncodeResultA MoonBit protobuf ecosystem lab for dynamic schema validation, compatibility testing, and AI code verification.