use std::error::Error;
use std::fmt;
use std::io::Write;
use std::marker::PhantomPinned;
use std::mem;
use std::path::Path;
use std::pin::Pin;
use crate::internal::{unsafe_ffi_conversions, BoolExt, CInt};
use crate::io::{CodedInputStream, CodedOutputStream, WriterStream, ZeroCopyOutputStream};
pub mod compiler;
pub mod io;
mod internal;
#[cxx::bridge(namespace = "protobuf_native")]
pub(crate) mod ffi {
unsafe extern "C++" {
include!("protobuf-native/src/internal.h");
include!("protobuf-native/src/lib.h");
#[namespace = "protobuf_native::internal"]
type CInt = crate::internal::CInt;
#[namespace = "google::protobuf::io"]
type ZeroCopyOutputStream = crate::io::ffi::ZeroCopyOutputStream;
#[namespace = "google::protobuf::io"]
type CodedInputStream = crate::io::ffi::CodedInputStream;
#[namespace = "google::protobuf::io"]
type CodedOutputStream = crate::io::ffi::CodedOutputStream;
#[namespace = "google::protobuf"]
type MessageLite;
fn NewMessageLite(message: &MessageLite) -> *mut MessageLite;
unsafe fn DeleteMessageLite(message: *mut MessageLite);
fn Clear(self: Pin<&mut MessageLite>);
fn IsInitialized(self: &MessageLite) -> bool;
unsafe fn MergeFromCodedStream(
self: Pin<&mut MessageLite>,
input: *mut CodedInputStream,
) -> bool;
unsafe fn SerializeToCodedStream(
self: &MessageLite,
output: *mut CodedOutputStream,
) -> bool;
unsafe fn SerializeToZeroCopyStream(
self: &MessageLite,
output: *mut ZeroCopyOutputStream,
) -> bool;
fn ByteSizeLong(self: &MessageLite) -> usize;
#[namespace = "google::protobuf"]
type Message;
#[namespace = "google::protobuf"]
type FileDescriptor;
unsafe fn DeleteFileDescriptor(proto: *mut FileDescriptor);
#[namespace = "google::protobuf"]
type DescriptorPool;
fn NewDescriptorPool() -> *mut DescriptorPool;
unsafe fn DeleteDescriptorPool(proto: *mut DescriptorPool);
fn BuildFile(
self: Pin<&mut DescriptorPool>,
proto: &FileDescriptorProto,
) -> *const FileDescriptor;
#[namespace = "google::protobuf"]
type FileDescriptorSet;
fn NewFileDescriptorSet() -> *mut FileDescriptorSet;
unsafe fn DeleteFileDescriptorSet(set: *mut FileDescriptorSet);
fn file_size(self: &FileDescriptorSet) -> CInt;
fn clear_file(self: Pin<&mut FileDescriptorSet>);
fn file(self: &FileDescriptorSet, i: CInt) -> &FileDescriptorProto;
fn mutable_file(self: Pin<&mut FileDescriptorSet>, i: CInt) -> *mut FileDescriptorProto;
fn add_file(self: Pin<&mut FileDescriptorSet>) -> *mut FileDescriptorProto;
#[namespace = "google::protobuf"]
type FileDescriptorProto;
fn NewFileDescriptorProto() -> *mut FileDescriptorProto;
unsafe fn DeleteFileDescriptorProto(proto: *mut FileDescriptorProto);
fn CopyFrom(self: Pin<&mut FileDescriptorProto>, from: &FileDescriptorProto);
fn MergeFrom(self: Pin<&mut FileDescriptorProto>, from: &FileDescriptorProto);
fn dependency_size(self: &FileDescriptorProto) -> CInt;
fn dependency(self: &FileDescriptorProto, i: CInt) -> &CxxString;
fn message_type_size(self: &FileDescriptorProto) -> CInt;
fn message_type(self: &FileDescriptorProto, i: CInt) -> &DescriptorProto;
#[namespace = "google::protobuf"]
type DescriptorProto;
unsafe fn DeleteDescriptorProto(proto: *mut DescriptorProto);
fn name(self: &DescriptorProto) -> &CxxString;
}
impl UniquePtr<MessageLite> {}
impl UniquePtr<Message> {}
}
mod private {
use std::pin::Pin;
use super::ffi;
pub trait MessageLite {
fn upcast(&self) -> &ffi::MessageLite;
fn upcast_mut(self: Pin<&mut Self>) -> Pin<&mut ffi::MessageLite>;
}
pub trait Message {}
}
pub trait DescriptorDatabase {
fn find_file_by_name(
self: Pin<&mut Self>,
filename: &Path,
) -> Result<Pin<Box<FileDescriptorProto>>, OperationFailedError>;
}
pub struct FileDescriptor {
_opaque: PhantomPinned,
}
impl FileDescriptor {
unsafe_ffi_conversions!(ffi::FileDescriptor);
}
impl Drop for FileDescriptor {
fn drop(&mut self) {
unsafe { ffi::DeleteFileDescriptor(self.as_ffi_mut_ptr_unpinned()) }
}
}
pub struct DescriptorPool {
_opaque: PhantomPinned,
}
impl Drop for DescriptorPool {
fn drop(&mut self) {
unsafe { ffi::DeleteDescriptorPool(self.as_ffi_mut_ptr_unpinned()) }
}
}
impl DescriptorPool {
pub fn new() -> Pin<Box<DescriptorPool>> {
let pool = ffi::NewDescriptorPool();
unsafe { Self::from_ffi_owned(pool) }
}
pub fn build_file(self: Pin<&mut Self>, proto: &FileDescriptorProto) -> &FileDescriptor {
let file = self.as_ffi_mut().BuildFile(proto.as_ffi());
unsafe { FileDescriptor::from_ffi_ptr(file) }
}
unsafe_ffi_conversions!(ffi::DescriptorPool);
}
pub struct Descriptor {}
pub trait MessageLite: private::MessageLite {
fn new(&self) -> Pin<Box<dyn MessageLite>> {
unsafe { DynMessageLite::from_ffi_owned(ffi::NewMessageLite(self.upcast())) }
}
fn clear(self: Pin<&mut Self>) {
self.upcast_mut().Clear()
}
fn is_initialized(&self) -> bool {
self.upcast().IsInitialized()
}
fn merge_from_coded_stream(
self: Pin<&mut Self>,
input: Pin<&mut CodedInputStream>,
) -> Result<(), OperationFailedError> {
unsafe {
self.upcast_mut()
.MergeFromCodedStream(input.as_ffi_mut_ptr())
.as_result()
}
}
fn serialize_to_coded_stream(
&self,
output: Pin<&mut CodedOutputStream>,
) -> Result<(), OperationFailedError> {
unsafe {
self.upcast()
.SerializeToCodedStream(output.as_ffi_mut_ptr())
.as_result()
}
}
fn serialize_to_zero_copy_stream(
&self,
output: Pin<&mut dyn ZeroCopyOutputStream>,
) -> Result<(), OperationFailedError> {
unsafe {
self.upcast()
.SerializeToZeroCopyStream(output.upcast_mut_ptr())
.as_result()
}
}
fn serialize_to_writer(&self, output: &mut dyn Write) -> Result<(), OperationFailedError> {
self.serialize_to_zero_copy_stream(WriterStream::new(output).as_mut())
}
fn serialize(&self) -> Result<Vec<u8>, OperationFailedError> {
let mut output = vec![];
self.serialize_to_writer(&mut output)?;
Ok(output)
}
fn byte_size(&self) -> usize {
self.upcast().ByteSizeLong()
}
}
struct DynMessageLite {
_opaque: PhantomPinned,
}
impl Drop for DynMessageLite {
fn drop(&mut self) {
unsafe { ffi::DeleteMessageLite(self.as_ffi_mut_ptr_unpinned()) }
}
}
impl DynMessageLite {
unsafe_ffi_conversions!(ffi::MessageLite);
}
impl MessageLite for DynMessageLite {}
impl private::MessageLite for DynMessageLite {
fn upcast(&self) -> &ffi::MessageLite {
unsafe { mem::transmute(self) }
}
fn upcast_mut(self: Pin<&mut Self>) -> Pin<&mut ffi::MessageLite> {
unsafe { mem::transmute(self) }
}
}
pub trait Message: private::Message + MessageLite {}
pub struct FileDescriptorSet {
_opaque: PhantomPinned,
}
impl Drop for FileDescriptorSet {
fn drop(&mut self) {
unsafe { ffi::DeleteFileDescriptorSet(self.as_ffi_mut_ptr_unpinned()) }
}
}
impl FileDescriptorSet {
fn new() -> Pin<Box<FileDescriptorSet>> {
let set = ffi::NewFileDescriptorSet();
unsafe { Self::from_ffi_owned(set) }
}
pub fn file_size(&self) -> usize {
self.as_ffi().file_size().expect_usize()
}
pub fn clear_file(self: Pin<&mut Self>) {
self.as_ffi_mut().clear_file()
}
pub fn file(&self, i: usize) -> &FileDescriptorProto {
let file = self.as_ffi().file(CInt::expect_from(i));
FileDescriptorProto::from_ffi_ref(file)
}
pub fn file_mut(self: Pin<&mut Self>, i: usize) -> Pin<&mut FileDescriptorProto> {
let file = self.as_ffi_mut().mutable_file(CInt::expect_from(i));
unsafe { FileDescriptorProto::from_ffi_mut(file) }
}
pub fn add_file(self: Pin<&mut Self>) -> Pin<&mut FileDescriptorProto> {
let file = self.as_ffi_mut().add_file();
unsafe { FileDescriptorProto::from_ffi_mut(file) }
}
unsafe_ffi_conversions!(ffi::FileDescriptorSet);
}
impl MessageLite for FileDescriptorSet {}
impl private::MessageLite for FileDescriptorSet {
fn upcast(&self) -> &ffi::MessageLite {
unsafe { mem::transmute(self) }
}
fn upcast_mut(self: Pin<&mut Self>) -> Pin<&mut ffi::MessageLite> {
unsafe { mem::transmute(self) }
}
}
impl Message for FileDescriptorSet {}
impl private::Message for FileDescriptorSet {}
pub struct FileDescriptorProto {
_opaque: PhantomPinned,
}
impl FileDescriptorProto {
fn new() -> Pin<Box<FileDescriptorProto>> {
let proto = ffi::NewFileDescriptorProto();
unsafe { Self::from_ffi_owned(proto) }
}
pub fn copy_from(self: Pin<&mut Self>, from: &FileDescriptorProto) {
self.as_ffi_mut().CopyFrom(from.as_ffi())
}
pub fn merge_from(self: Pin<&mut Self>, from: &FileDescriptorProto) {
self.as_ffi_mut().MergeFrom(from.as_ffi())
}
pub fn dependency_size(&self) -> usize {
self.as_ffi().dependency_size().expect_usize()
}
pub fn dependency(&self, i: usize) -> &[u8] {
if i >= self.dependency_size() {
panic!(
"index out of bounds: the length is {} but the index is {}",
self.dependency_size(),
i
);
}
self.as_ffi().dependency(CInt::expect_from(i)).as_bytes()
}
pub fn message_type_size(&self) -> usize {
self.as_ffi().message_type_size().expect_usize()
}
pub fn message_type(&self, i: usize) -> &DescriptorProto {
if i >= self.message_type_size() {
panic!(
"index out of bounds: the length is {} but the index is {}",
self.message_type_size(),
i
);
}
DescriptorProto::from_ffi_ref(self.as_ffi().message_type(CInt::expect_from(i)))
}
unsafe_ffi_conversions!(ffi::FileDescriptorProto);
}
impl Drop for FileDescriptorProto {
fn drop(&mut self) {
unsafe { ffi::DeleteFileDescriptorProto(self.as_ffi_mut_ptr_unpinned()) }
}
}
impl MessageLite for FileDescriptorProto {}
impl private::MessageLite for FileDescriptorProto {
fn upcast(&self) -> &ffi::MessageLite {
unsafe { mem::transmute(self) }
}
fn upcast_mut(self: Pin<&mut Self>) -> Pin<&mut ffi::MessageLite> {
unsafe { mem::transmute(self) }
}
}
impl Message for FileDescriptorProto {}
impl private::Message for FileDescriptorProto {}
pub struct DescriptorProto {
_opaque: PhantomPinned,
}
impl Drop for DescriptorProto {
fn drop(&mut self) {
unsafe { ffi::DeleteDescriptorProto(self.as_ffi_mut_ptr_unpinned()) }
}
}
impl DescriptorProto {
pub fn name(&self) -> &[u8] {
self.as_ffi().name().as_bytes()
}
unsafe_ffi_conversions!(ffi::DescriptorProto);
}
impl MessageLite for DescriptorProto {}
impl private::MessageLite for DescriptorProto {
fn upcast(&self) -> &ffi::MessageLite {
unsafe { mem::transmute(self) }
}
fn upcast_mut(self: Pin<&mut Self>) -> Pin<&mut ffi::MessageLite> {
unsafe { mem::transmute(self) }
}
}
impl Message for DescriptorProto {}
impl private::Message for DescriptorProto {}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct OperationFailedError;
impl fmt::Display for OperationFailedError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("operation failed")
}
}
impl Error for OperationFailedError {}