// The protobuf data model: the field kinds, the value union, and the raw bytes
// of unknown fields. https://protobuf.dev/programming-guides/proto3/
// The language version a file declares.
///|
#derive(Eq)
pub(all) enum Syntax {
Proto2
Proto3
Editions
}
///|
pub extend Syntax with Eq::{equal, not_equal}
///|
pub fn Syntax::code(self : Syntax) -> Int32 {
match self {
Proto2 => 2
Proto3 => 3
Editions => 4
}
}
///|
pub fn Syntax::of(code : Int32) -> Syntax? {
match code {
2 => Some(Proto2)
3 => Some(Proto3)
4 => Some(Editions)
_ => None
}
}
///|
/// Whether a field appears zero or one times, exactly once, or any number of
/// times.
#derive(Eq)
pub(all) enum Cardinality {
Optional
Required
Repeated
}
///|
pub extend Cardinality with Eq::{equal, not_equal}
///|
pub fn Cardinality::code(self : Cardinality) -> Int32 {
match self {
Optional => 1
Required => 2
Repeated => 3
}
}
///|
pub fn Cardinality::of(code : Int32) -> Cardinality? {
match code {
1 => Some(Optional)
2 => Some(Required)
3 => Some(Repeated)
_ => None
}
}
///|
/// The eighteen field kinds, numbered as `descriptor.proto` numbers them.
#derive(Eq)
pub(all) enum Kind {
Double
Float
Int64
Uint64
Int32
Fixed64
Fixed32
Bool
String
Group
Message
Bytes
Uint32
Enum
Sfixed32
Sfixed64
Sint32
Sint64
}
///|
pub extend Kind with Eq::{equal, not_equal}
///|
/// The `descriptor.proto` number of the kind.
pub fn Kind::code(self : Kind) -> Int32 {
match self {
Double => 1
Float => 2
Int64 => 3
Uint64 => 4
Int32 => 5
Fixed64 => 6
Fixed32 => 7
Bool => 8
String => 9
Group => 10
Message => 11
Bytes => 12
Uint32 => 13
Enum => 14
Sfixed32 => 15
Sfixed64 => 16
Sint32 => 17
Sint64 => 18
}
}
///|
/// The kind for a `descriptor.proto` number.
pub fn Kind::of(code : Int32) -> Kind? {
match code {
1 => Some(Double)
2 => Some(Float)
3 => Some(Int64)
4 => Some(Uint64)
5 => Some(Int32)
6 => Some(Fixed64)
7 => Some(Fixed32)
8 => Some(Bool)
9 => Some(String)
10 => Some(Group)
11 => Some(Message)
12 => Some(Bytes)
13 => Some(Uint32)
14 => Some(Enum)
15 => Some(Sfixed32)
16 => Some(Sfixed64)
17 => Some(Sint32)
18 => Some(Sint64)
_ => None
}
}
///|
/// Whether the kind is a number, and so packable when repeated.
pub fn Kind::is_numeric(self : Kind) -> Bool {
match self {
String | Bytes | Message | Group => false
_ => true
}
}
///|
/// Whether the kind is a message or a group, and so needs a nested message.
pub fn Kind::is_message(self : Kind) -> Bool {
match self {
Message | Group => true
_ => false
}
}
///|
/// Whether the kind is the enum kind.
pub fn Kind::is_enum(self : Kind) -> Bool {
self == Enum
}
///|
/// A map key: the six scalar kinds a map field's key may take.
#derive(Eq)
pub(all) enum MapKey {
Bool(Bool)
Int32(Int32)
Int64(Int64)
Uint32(UInt32)
Uint64(UInt64)
String(String)
}
///|
pub extend MapKey with Eq::{equal, not_equal}
///|
/// One field value. A composite value holds a reference to a list, map or
/// message, so mutation through it is visible to the message that owns it.
pub(all) enum Value {
Invalid
Bool(Bool)
Int32(Int32)
Int64(Int64)
Uint32(UInt32)
Uint64(UInt64)
Float(@float.Float)
Double(Double)
String(String)
Bytes(Bytes)
Enum(Int32)
Message(&Message)
ListView(&ListField)
MapView(&MapField)
}
///|
/// The empty value, used where a field is absent and a `Value` is still
/// required.
pub let invalid : Value = Invalid
///|
pub fn Value::is_valid(self : Value) -> Bool {
match self {
Invalid => false
_ => true
}
}
///|
/// The value as a bool; aborts when it is not one.
pub fn Value::bool(self : Value) -> Bool {
match self {
Bool(v) => v
_ => abort("value is not a bool")
}
}
///|
/// The value as an integer; `Int32` and `Int64` both widen.
pub fn Value::int(self : Value) -> Int64 {
match self {
Int32(v) => v.to_int64()
Int64(v) => v
_ => abort("value is not an integer")
}
}
///|
/// The value as an unsigned integer; `Uint32` and `Uint64` both widen.
pub fn Value::uint(self : Value) -> UInt64 {
match self {
Uint32(v) => v.to_uint64()
Uint64(v) => v
_ => abort("value is not an unsigned integer")
}
}
///|
/// The value as a double; `Float` widens.
pub fn Value::float(self : Value) -> Double {
match self {
Float(v) => v.to_double()
Double(v) => v
_ => abort("value is not a float")
}
}
///|
pub fn Value::string(self : Value) -> String {
match self {
String(v) => v
_ => abort("value is not a string")
}
}
///|
pub fn Value::bytes(self : Value) -> Bytes {
match self {
Bytes(v) => v
_ => abort("value is not bytes")
}
}
///|
pub fn Value::enum_number(self : Value) -> Int32 {
match self {
Enum(v) => v
_ => abort("value is not an enum")
}
}
///|
pub fn Value::message(self : Value) -> &Message {
match self {
Message(v) => v
_ => abort("value is not a message")
}
}
///|
pub fn Value::list(self : Value) -> &ListField {
match self {
ListView(v) => v
_ => abort("value is not a list")
}
}
///|
pub fn Value::map(self : Value) -> &MapField {
match self {
MapView(v) => v
_ => abort("value is not a map")
}
}
///|
/// The value as a map key, or `None` when its kind cannot be a key.
pub fn Value::map_key(self : Value) -> MapKey? {
match self {
Bool(v) => Some(Bool(v))
Int32(v) => Some(Int32(v))
Int64(v) => Some(Int64(v))
Uint32(v) => Some(Uint32(v))
Uint64(v) => Some(Uint64(v))
String(v) => Some(String(v))
_ => None
}
}
///|
/// A value for a map key.
pub fn MapKey::value(self : MapKey) -> Value {
match self {
Bool(v) => Bool(v)
Int32(v) => Int32(v)
Int64(v) => Int64(v)
Uint32(v) => Uint32(v)
Uint64(v) => Uint64(v)
String(v) => String(v)
}
}
///|
/// Structural equality for scalars; composites compare by identity, because
/// semantic equality is a descriptor-driven walk in `proto.equal`.
pub fn Value::equal(self : Value, other : Value) -> Bool {
match (self, other) {
(Invalid, Invalid) => true
(Bool(a), Bool(b)) => a == b
(Int32(a), Int32(b)) => a == b
(Int64(a), Int64(b)) => a == b
(Uint32(a), Uint32(b)) => a == b
(Uint64(a), Uint64(b)) => a == b
(Float(a), Float(b)) => a == b
(Double(a), Double(b)) => a == b
(String(a), String(b)) => a == b
(Bytes(a), Bytes(b)) => a == b
(Enum(a), Enum(b)) => a == b
(Message(_), Message(_)) => false
(ListView(_), ListView(_)) => false
(MapView(_), MapView(_)) => false
_ => false
}
}
///|
/// The bytes of every unknown field a message carried, tag and body included.
pub(all) struct RawFields(Bytes)
///|
pub fn RawFields::from_bytes(bytes : Bytes) -> RawFields {
RawFields(bytes)
}
///|
pub fn RawFields::bytes(self : RawFields) -> Bytes {
self.0
}
///|
pub fn RawFields::is_empty(self : RawFields) -> Bool {
self.0.length() == 0
}
///|
/// Whether the bytes are a syntactically valid sequence of fields.
pub fn RawFields::is_valid(self : RawFields) -> Bool {
let body = self.0
let mut at = 0
while at < body.length() {
let next = @wire.skip_field(body[:], at~) catch { _ => -1 }
if next < 0 {
return false
}
at = next
}
true
}
///|
/// Whether an optional field slot has a value.
pub fn[T] is_set(value : T?) -> Bool {
match value {
Some(_) => true
None => false
}
}
///|
/// A 32-bit float carried as the double the wire and the encoders use.
pub fn float_value(value : Double) -> Value {
Float(@float.Float::from_double(value))
}
///|
pub fn MapKey::bool(self : MapKey) -> Bool {
match self {
Bool(value) => value
_ => abort("map key is not a bool")
}
}
///|
pub fn MapKey::int(self : MapKey) -> Int64 {
match self {
Int32(value) => value.to_int64()
Int64(value) => value
_ => abort("map key is not an integer")
}
}
///|
pub fn MapKey::uint(self : MapKey) -> UInt64 {
match self {
Uint32(value) => value.to_uint64()
Uint64(value) => value
_ => abort("map key is not an unsigned integer")
}
}
///|
pub fn MapKey::string(self : MapKey) -> String {
match self {
String(value) => value
_ => abort("map key is not a string")
}
}