// Descriptors are plain data: the structure a file declares, with cross-type
// references kept as fully-qualified names. A name is resolved through a
// registry at the moment a value is built, which is what keeps a file's
// declarations from needing pointers back to one another.
///|
pub(all) struct EnumValueDescriptor {
name : String
number : Int32
full_name : String
}
///|
pub(all) struct EnumDescriptor {
name : String
full_name : String
values : Array[EnumValueDescriptor]
closed : Bool
file_path : String
}
///|
/// The value with `number`, or `None`.
pub fn EnumDescriptor::value_by_number(
self : EnumDescriptor,
number : Int32,
) -> EnumValueDescriptor? {
for value in self.values {
if value.number == number {
return Some(value)
}
}
None
}
///|
/// The value with `name`, or `None`.
pub fn EnumDescriptor::value_by_name(
self : EnumDescriptor,
name : String,
) -> EnumValueDescriptor? {
for value in self.values {
if value.name == name {
return Some(value)
}
}
None
}
///|
pub(all) struct OneofDescriptor {
name : String
synthetic : Bool
/// The field numbers that belong to this oneof, in declaration order.
field_numbers : Array[Int32]
}
///|
pub(all) struct FieldDescriptor {
name : String
full_name : String
number : Int32
kind : Kind
cardinality : Cardinality
json_name : String
text_name : String
has_presence : Bool
is_extension : Bool
is_map : Bool
packed : Bool
/// The index of the oneof this field belongs to, when it belongs to one.
oneof_index : Int32?
/// The fully-qualified message type for `Message` and `Group` fields.
message_type : String?
/// The fully-qualified enum type for `Enum` fields.
enum_type : String?
has_default : Bool
default_value : Value
default_enum_name : String?
/// The fully-qualified name of the message this field belongs to.
containing_message : String
/// For a map field, the entry's key and value descriptors.
map_key_field : FieldDescriptor?
map_value_field : FieldDescriptor?
}
///|
/// Whether the field is repeated and not a map, so its value is a list.
pub fn FieldDescriptor::is_list(self : FieldDescriptor) -> Bool {
self.cardinality == Repeated && !self.is_map
}
///|
/// Whether the field is a map, so its value is a map rather than a list.
pub fn FieldDescriptor::is_map_field(self : FieldDescriptor) -> Bool {
self.is_map
}
///|
pub(all) struct MessageDescriptor {
name : String
full_name : String
syntax : Syntax
fields : Array[FieldDescriptor]
oneofs : Array[OneofDescriptor]
is_map_entry : Bool
reserved_names : Array[String]
reserved_ranges : Array[(Int32, Int32)]
required_numbers : Array[Int32]
extension_ranges : Array[(Int32, Int32)]
nested_messages : Array[MessageDescriptor]
nested_enums : Array[EnumDescriptor]
nested_extensions : Array[FieldDescriptor]
file_path : String
/// The message entry's key and value fields, precomputed for a map entry.
map_key : FieldDescriptor?
map_value : FieldDescriptor?
}
///|
/// The field with `number`, or `None`.
pub fn MessageDescriptor::field_by_number(
self : MessageDescriptor,
number : Int32,
) -> FieldDescriptor? {
for field in self.fields {
if field.number == number {
return Some(field)
}
}
None
}
///|
/// The field with the proto `name`, or `None`.
pub fn MessageDescriptor::field_by_name(
self : MessageDescriptor,
name : String,
) -> FieldDescriptor? {
for field in self.fields {
if field.name == name {
return Some(field)
}
}
None
}
///|
/// The field whose JSON name is `name`, or `None`.
pub fn MessageDescriptor::field_by_json_name(
self : MessageDescriptor,
name : String,
) -> FieldDescriptor? {
for field in self.fields {
if field.json_name == name {
return Some(field)
}
}
None
}
///|
/// The oneof that owns `number`, or `None`.
pub fn MessageDescriptor::oneof_of_field(
self : MessageDescriptor,
number : Int32,
) -> OneofDescriptor? {
for oneof in self.oneofs {
for field_number in oneof.field_numbers {
if field_number == number {
return Some(oneof)
}
}
}
None
}
///|
pub(all) struct MethodDescriptor {
name : String
full_name : String
input_type : String
output_type : String
streaming_client : Bool
streaming_server : Bool
}
///|
pub(all) struct ServiceDescriptor {
name : String
full_name : String
methods : Array[MethodDescriptor]
file_path : String
}
///|
pub(all) struct FileDescriptor {
path : String
package_name : String
syntax : Syntax
messages : Array[MessageDescriptor]
enums : Array[EnumDescriptor]
services : Array[ServiceDescriptor]
extensions : Array[FieldDescriptor]
dependencies : Array[String]
public_dependencies : Array[String]
/// `edition = "2023"` when the file declares one.
edition : String?
/// Options written in the file, keyed by the declared name they belong to;
/// the file's own options sit under the empty key.
option_map : Array[(String, Array[(String, String)])]
}
///|
/// The options written on `name` in this file, as (name, value) pairs.
pub fn FileDescriptor::options_of(
self : FileDescriptor,
name : String,
) -> Array[(String, String)] {
for entry in self.option_map {
if entry.0 == name {
return entry.1
}
}
[]
}
///|
/// The value of one option on `name`, if it was written.
pub fn FileDescriptor::option_of(
self : FileDescriptor,
name : String,
option : String,
) -> String? {
for pair in self.options_of(name) {
if pair.0 == option {
return Some(pair.1)
}
}
None
}
///|
/// The file's own name, without directories.
pub fn FileDescriptor::name(self : FileDescriptor) -> String {
let path = self.path
let mut start = 0
for i in 0.. String {
if package_name.length() == 0 {
name
} else {
package_name + "." + name
}
}
///|
/// The last segment of a qualified name.
pub fn short_name(full_name : String) -> String {
let mut start = 0
for i in 0.. String {
let mut last = -1
for i in 0..