Import protobuf-json-mapping crate.

protobuf-json-mapping has crate dependency on protobuf = 3.2.0

Bug: 275568385
Bug: 272591694
Test: m libprotobuf_json_mapping
Change-Id: Ide77fbc6afec59e3c22bf3c6d9b56b58c40f27fb
diff --git a/src/print.rs b/src/print.rs
new file mode 100644
index 0000000..eef44ca
--- /dev/null
+++ b/src/print.rs
@@ -0,0 +1,586 @@
+use std::fmt;
+use std::fmt::Write as fmt_Write;
+
+use protobuf::reflect::EnumDescriptor;
+use protobuf::reflect::EnumValueDescriptor;
+use protobuf::reflect::MessageRef;
+use protobuf::reflect::ReflectFieldRef;
+use protobuf::reflect::ReflectMapRef;
+use protobuf::reflect::ReflectRepeatedRef;
+use protobuf::reflect::ReflectValueRef;
+use protobuf::reflect::RuntimeFieldType;
+use protobuf::reflect::RuntimeType;
+use protobuf::well_known_types::any::Any;
+use protobuf::well_known_types::duration::Duration;
+use protobuf::well_known_types::field_mask::FieldMask;
+use protobuf::well_known_types::struct_::value;
+use protobuf::well_known_types::struct_::ListValue;
+use protobuf::well_known_types::struct_::NullValue;
+use protobuf::well_known_types::struct_::Struct;
+use protobuf::well_known_types::struct_::Value;
+use protobuf::well_known_types::timestamp::Timestamp;
+use protobuf::well_known_types::wrappers::BoolValue;
+use protobuf::well_known_types::wrappers::BytesValue;
+use protobuf::well_known_types::wrappers::DoubleValue;
+use protobuf::well_known_types::wrappers::FloatValue;
+use protobuf::well_known_types::wrappers::Int32Value;
+use protobuf::well_known_types::wrappers::Int64Value;
+use protobuf::well_known_types::wrappers::StringValue;
+use protobuf::well_known_types::wrappers::UInt32Value;
+use protobuf::well_known_types::wrappers::UInt64Value;
+use protobuf::MessageDyn;
+
+use crate::base64;
+use crate::float;
+use crate::rfc_3339::TmUtc;
+use crate::well_known_wrapper::WellKnownWrapper;
+
+#[derive(Debug, thiserror::Error)]
+enum PrintErrorInner {
+    #[error(transparent)]
+    Fmt(fmt::Error),
+    #[error("JSON printing of Any is not implemented")]
+    AnyPrintingIsNotImplemented,
+    #[error("Negative nanoseconds in timestamp")]
+    TimestampNegativeNanos,
+    #[error("Unknown struct value kind")]
+    UnknownStructValueKind,
+}
+
+/// Print to JSON error.
+#[derive(Debug, thiserror::Error)]
+#[error(transparent)]
+pub struct PrintError(PrintErrorInner);
+
+impl From<fmt::Error> for PrintError {
+    fn from(e: fmt::Error) -> Self {
+        PrintError(PrintErrorInner::Fmt(e))
+    }
+}
+
+pub type PrintResult<T> = Result<T, PrintError>;
+
+struct Printer {
+    buf: String,
+    print_options: PrintOptions,
+}
+
+trait PrintableToJson {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()>;
+}
+
+trait JsonFloat: fmt::Display + fmt::Debug + PrintableToJson {
+    fn is_nan(&self) -> bool;
+    fn is_pos_infinity(&self) -> bool;
+    fn is_neg_infinity(&self) -> bool;
+
+    fn print_to_json_impl(&self, w: &mut String) -> PrintResult<()> {
+        Ok(if self.is_nan() {
+            write!(w, "\"{}\"", float::PROTOBUF_JSON_NAN)?
+        } else if self.is_pos_infinity() {
+            write!(w, "\"{}\"", float::PROTOBUF_JSON_INF)?
+        } else if self.is_neg_infinity() {
+            write!(w, "\"{}\"", float::PROTOBUF_JSON_MINUS_INF)?
+        } else {
+            write!(w, "{:?}", self)?
+        })
+    }
+}
+
+impl JsonFloat for f32 {
+    fn is_nan(&self) -> bool {
+        f32::is_nan(*self)
+    }
+
+    fn is_pos_infinity(&self) -> bool {
+        f32::is_infinite(*self) && self > &0.0
+    }
+
+    fn is_neg_infinity(&self) -> bool {
+        f32::is_infinite(*self) && self < &0.0
+    }
+}
+
+impl PrintableToJson for f32 {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        Ok(self.print_to_json_impl(&mut w.buf)?)
+    }
+}
+
+impl JsonFloat for f64 {
+    fn is_nan(&self) -> bool {
+        f64::is_nan(*self)
+    }
+
+    fn is_pos_infinity(&self) -> bool {
+        f64::is_infinite(*self) && self > &0.0
+    }
+
+    fn is_neg_infinity(&self) -> bool {
+        f64::is_infinite(*self) && self < &0.0
+    }
+}
+
+impl PrintableToJson for f64 {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        self.print_to_json_impl(&mut w.buf)
+    }
+}
+
+impl PrintableToJson for u64 {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        // 64-bit integers are quoted by default
+        Ok(write!(w.buf, "\"{}\"", self)?)
+    }
+}
+
+impl PrintableToJson for i64 {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        // 64-bit integers are quoted by default
+        Ok(write!(w.buf, "\"{}\"", self)?)
+    }
+}
+
+impl PrintableToJson for u32 {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        Ok(write!(w.buf, "{}", self)?)
+    }
+}
+
+impl PrintableToJson for i32 {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        Ok(write!(w.buf, "{}", self)?)
+    }
+}
+
+impl PrintableToJson for bool {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        Ok(write!(w.buf, "{}", self)?)
+    }
+}
+
+impl PrintableToJson for str {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        write!(w.buf, "\"")?;
+        for c in self.chars() {
+            match c {
+                '"' => write!(w.buf, "\\\""),
+                '\\' => write!(w.buf, "\\\\"),
+                '\n' => write!(w.buf, "\\n"),
+                '\r' => write!(w.buf, "\\r"),
+                '\t' => write!(w.buf, "\\t"),
+                c if c.is_control() => write!(w.buf, "\\u{:04x}", c as u32),
+                c => write!(w.buf, "{}", c),
+            }?;
+        }
+        write!(w.buf, "\"")?;
+        Ok(())
+    }
+}
+
+impl PrintableToJson for String {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        self.as_str().print_to_json(w)
+    }
+}
+
+impl PrintableToJson for [u8] {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        let encoded = base64::encode(self);
+        encoded.print_to_json(w)
+    }
+}
+
+impl PrintableToJson for Vec<u8> {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        self.as_slice().print_to_json(w)
+    }
+}
+
+impl<'a> PrintableToJson for ReflectValueRef<'a> {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        match self {
+            ReflectValueRef::U32(v) => w.print_printable(v),
+            ReflectValueRef::U64(v) => w.print_printable(v),
+            ReflectValueRef::I32(v) => w.print_printable(v),
+            ReflectValueRef::I64(v) => w.print_printable(v),
+            ReflectValueRef::F32(v) => w.print_printable(v),
+            ReflectValueRef::F64(v) => w.print_printable(v),
+            ReflectValueRef::Bool(v) => w.print_printable(v),
+            ReflectValueRef::String(v) => w.print_printable::<str>(v),
+            ReflectValueRef::Bytes(v) => w.print_printable::<[u8]>(v),
+            ReflectValueRef::Enum(d, v) => w.print_enum(d, *v),
+            ReflectValueRef::Message(v) => w.print_message(v),
+        }
+    }
+}
+
+impl PrintableToJson for Duration {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        let sign = if self.seconds >= 0 { "" } else { "-" };
+        Ok(write!(
+            w.buf,
+            "\"{}{}.{:09}s\"",
+            sign,
+            self.seconds.abs(),
+            self.nanos.abs()
+        )?)
+    }
+}
+
+impl PrintableToJson for Timestamp {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        if self.nanos < 0 {
+            return Err(PrintError(PrintErrorInner::TimestampNegativeNanos));
+        }
+        let tm_utc = TmUtc::from_protobuf_timestamp(self.seconds, self.nanos as u32);
+        w.print_printable(&tm_utc.to_string())
+    }
+}
+
+impl PrintableToJson for FieldMask {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        w.print_printable(&self.paths.join(","))
+    }
+}
+
+impl PrintableToJson for Any {
+    fn print_to_json(&self, _w: &mut Printer) -> PrintResult<()> {
+        Err(PrintError(PrintErrorInner::AnyPrintingIsNotImplemented))
+    }
+}
+
+impl PrintableToJson for Value {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        match self.kind {
+            // None should not be possible here, but it's better to print null than crash
+            None => w.print_json_null(),
+            Some(value::Kind::NullValue(null_value)) => {
+                match null_value.enum_value() {
+                    Ok(value) => w.print_wk_null_value(&value),
+                    Err(n) => {
+                        // Practically not possible, but it is safer this way.
+                        w.print_printable(&n)
+                    }
+                }
+            }
+            Some(value::Kind::BoolValue(b)) => w.print_printable(&b),
+            Some(value::Kind::NumberValue(n)) => w.print_printable(&n),
+            Some(value::Kind::StringValue(ref s)) => w.print_printable::<String>(&s),
+            Some(value::Kind::StructValue(ref s)) => w.print_printable(&s),
+            Some(value::Kind::ListValue(ref l)) => w.print_printable(&l),
+            Some(_) => Err(PrintError(PrintErrorInner::UnknownStructValueKind)),
+        }
+    }
+}
+
+impl PrintableToJson for ListValue {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        w.print_list(&self.values)
+    }
+}
+
+impl PrintableToJson for Struct {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        w.print_object(&self.fields)
+    }
+}
+
+impl<'a, P: PrintableToJson> PrintableToJson for &'a P {
+    fn print_to_json(&self, w: &mut Printer) -> PrintResult<()> {
+        (*self).print_to_json(w)
+    }
+}
+
+trait ObjectKey {
+    fn print_object_key(&self, w: &mut Printer) -> PrintResult<()>;
+}
+
+impl<'a> ObjectKey for ReflectValueRef<'a> {
+    fn print_object_key(&self, w: &mut Printer) -> PrintResult<()> {
+        match self {
+            ReflectValueRef::String(v) => return w.print_printable::<str>(v),
+            ReflectValueRef::Bytes(v) => return w.print_printable::<[u8]>(v),
+            // do not quote, because printable is quoted
+            ReflectValueRef::U64(v) => return w.print_printable(v),
+            ReflectValueRef::I64(v) => return w.print_printable(v),
+            ReflectValueRef::Enum(d, v) if !w.print_options.enum_values_int => {
+                return w.print_enum(d, *v)
+            }
+            _ => {}
+        }
+
+        write!(w.buf, "\"")?;
+
+        match self {
+            ReflectValueRef::U32(v) => w.print_printable(v),
+            ReflectValueRef::I32(v) => w.print_printable(v),
+            ReflectValueRef::Bool(v) => w.print_printable(v),
+            ReflectValueRef::Enum(d, v) if w.print_options.enum_values_int => w.print_enum(d, *v),
+            ReflectValueRef::Enum(..)
+            | ReflectValueRef::U64(_)
+            | ReflectValueRef::I64(_)
+            | ReflectValueRef::String(_)
+            | ReflectValueRef::Bytes(_) => unreachable!(),
+            ReflectValueRef::F32(_) | ReflectValueRef::F64(_) | ReflectValueRef::Message(_) => {
+                panic!("cannot be object key")
+            }
+        }?;
+
+        write!(w.buf, "\"")?;
+
+        Ok(())
+    }
+}
+
+impl ObjectKey for String {
+    fn print_object_key(&self, w: &mut Printer) -> PrintResult<()> {
+        w.print_printable(self)
+    }
+}
+
+impl<'a, O: ObjectKey> ObjectKey for &'a O {
+    fn print_object_key(&self, w: &mut Printer) -> PrintResult<()> {
+        (*self).print_object_key(w)
+    }
+}
+
+impl Printer {
+    fn print_comma_but_first(&mut self, first: &mut bool) -> fmt::Result {
+        if *first {
+            *first = false;
+            Ok(())
+        } else {
+            write!(self.buf, ", ")
+        }
+    }
+
+    fn print_json_null(&mut self) -> PrintResult<()> {
+        Ok(write!(self.buf, "null")?)
+    }
+
+    fn print_printable<F: PrintableToJson + ?Sized>(&mut self, f: &F) -> PrintResult<()> {
+        f.print_to_json(self)
+    }
+
+    fn print_list<I>(&mut self, items: I) -> PrintResult<()>
+    where
+        I: IntoIterator,
+        I::Item: PrintableToJson,
+    {
+        write!(self.buf, "[")?;
+        for (i, item) in items.into_iter().enumerate() {
+            if i != 0 {
+                write!(self.buf, ", ")?;
+            }
+            self.print_printable(&item)?;
+        }
+        write!(self.buf, "]")?;
+        Ok(())
+    }
+
+    fn print_repeated(&mut self, repeated: &ReflectRepeatedRef) -> PrintResult<()> {
+        self.print_list(repeated)
+    }
+
+    fn print_object<I, K, V>(&mut self, items: I) -> PrintResult<()>
+    where
+        I: IntoIterator<Item = (K, V)>,
+        K: ObjectKey,
+        V: PrintableToJson,
+    {
+        write!(self.buf, "{{")?;
+        for (i, (k, v)) in items.into_iter().enumerate() {
+            if i != 0 {
+                write!(self.buf, ", ")?;
+            }
+            k.print_object_key(self)?;
+            write!(self.buf, ": ")?;
+            self.print_printable(&v)?;
+        }
+        write!(self.buf, "}}")?;
+        Ok(())
+    }
+
+    fn print_map(&mut self, map: &ReflectMapRef) -> PrintResult<()> {
+        self.print_object(map.into_iter())
+    }
+
+    fn print_enum_known(&mut self, value: &EnumValueDescriptor) -> PrintResult<()> {
+        if let Some(null_value) = value.cast() {
+            self.print_wk_null_value(&null_value)
+        } else {
+            if self.print_options.enum_values_int {
+                self.print_printable(&value.value())
+            } else {
+                Ok(write!(self.buf, "\"{}\"", value.name())?)
+            }
+        }
+    }
+
+    fn print_enum(&mut self, descriptor: &EnumDescriptor, v: i32) -> PrintResult<()> {
+        if self.print_options.enum_values_int {
+            self.print_printable(&v)
+        } else {
+            match descriptor.value_by_number(v) {
+                Some(value) => self.print_enum_known(&value),
+                None => self.print_printable(&v),
+            }
+        }
+    }
+
+    fn print_message(&mut self, message: &MessageRef) -> PrintResult<()> {
+        if let Some(duration) = message.downcast_ref::<Duration>() {
+            self.print_printable(duration)
+        } else if let Some(timestamp) = message.downcast_ref::<Timestamp>() {
+            self.print_printable(timestamp)
+        } else if let Some(field_mask) = message.downcast_ref::<FieldMask>() {
+            self.print_printable(field_mask)
+        } else if let Some(any) = message.downcast_ref::<Any>() {
+            self.print_printable(any)
+        } else if let Some(value) = message.downcast_ref::<Value>() {
+            self.print_printable(value)
+        } else if let Some(value) = message.downcast_ref::<DoubleValue>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<FloatValue>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<Int64Value>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<UInt64Value>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<Int32Value>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<UInt32Value>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<BoolValue>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<StringValue>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<BytesValue>() {
+            self.print_wrapper(value)
+        } else if let Some(value) = message.downcast_ref::<ListValue>() {
+            self.print_printable(value)
+        } else if let Some(value) = message.downcast_ref::<Struct>() {
+            self.print_printable(value)
+        } else {
+            self.print_regular_message(message)
+        }
+    }
+
+    fn print_regular_message(&mut self, message: &MessageRef) -> Result<(), PrintError> {
+        let descriptor = message.descriptor_dyn();
+
+        write!(self.buf, "{{")?;
+        let mut first = true;
+        for field in descriptor.fields() {
+            let json_field_name = if self.print_options.proto_field_name {
+                field.name()
+            } else {
+                field.json_name()
+            };
+
+            let field_type = field.runtime_field_type();
+
+            match field.get_reflect(&**message) {
+                ReflectFieldRef::Optional(v) => match v.value() {
+                    None => {
+                        if self.print_options.always_output_default_values {
+                            let is_message = match field_type {
+                                RuntimeFieldType::Singular(s) => match s {
+                                    RuntimeType::Message(_) => true,
+                                    _ => false,
+                                },
+                                _ => unreachable!(),
+                            };
+
+                            let is_oneof = field.proto().has_oneof_index();
+
+                            if !is_message && !is_oneof {
+                                let v = field.get_singular_field_or_default(&**message);
+                                self.print_comma_but_first(&mut first)?;
+                                write!(self.buf, "\"{}\": ", json_field_name)?;
+                                self.print_printable(&v)?;
+                            }
+                        }
+                    }
+                    Some(v) => {
+                        self.print_comma_but_first(&mut first)?;
+                        write!(self.buf, "\"{}\": ", json_field_name)?;
+                        self.print_printable(&v)?;
+                    }
+                },
+                ReflectFieldRef::Repeated(v) => {
+                    if !v.is_empty() || self.print_options.always_output_default_values {
+                        self.print_comma_but_first(&mut first)?;
+                        write!(self.buf, "\"{}\": ", json_field_name)?;
+                        self.print_repeated(&v)?;
+                    }
+                }
+                ReflectFieldRef::Map(v) => {
+                    if !v.is_empty() || self.print_options.always_output_default_values {
+                        self.print_comma_but_first(&mut first)?;
+                        write!(self.buf, "\"{}\": ", json_field_name)?;
+                        self.print_map(&v)?;
+                    }
+                }
+            }
+        }
+        write!(self.buf, "}}")?;
+        Ok(())
+    }
+
+    fn print_wk_null_value(&mut self, _null_value: &NullValue) -> PrintResult<()> {
+        self.print_json_null()
+    }
+
+    fn print_wrapper<W>(&mut self, value: &W) -> PrintResult<()>
+    where
+        W: WellKnownWrapper,
+        W::Underlying: PrintableToJson,
+    {
+        self.print_printable(value.get_ref())
+    }
+}
+
+/// Options for printing JSON to string
+///
+/// # Examples
+///
+/// ```
+/// let print_options = protobuf_json_mapping::PrintOptions {
+///     enum_values_int: true,
+///     ..Default::default()
+/// };
+/// ```
+#[derive(Default, Debug, Clone)]
+pub struct PrintOptions {
+    /// Use ints instead of strings for enums.
+    ///
+    /// Note both string or int can be parsed.
+    pub enum_values_int: bool,
+    /// Use protobuf field names instead of `lowerCamelCase` which is used by default.
+    /// Note both names are supported when JSON is parsed.
+    pub proto_field_name: bool,
+    /// Output field default values.
+    pub always_output_default_values: bool,
+    /// Prevent initializing `PrintOptions` enumerating all field.
+    pub _future_options: (),
+}
+
+/// Serialize message to JSON according to protobuf specification.
+pub fn print_to_string_with_options(
+    message: &dyn MessageDyn,
+    print_options: &PrintOptions,
+) -> PrintResult<String> {
+    let mut printer = Printer {
+        buf: String::new(),
+        print_options: print_options.clone(),
+    };
+    printer.print_message(&MessageRef::from(message))?;
+    Ok(printer.buf)
+}
+
+/// Serialize message to JSON according to protobuf specification.
+pub fn print_to_string(message: &dyn MessageDyn) -> PrintResult<String> {
+    print_to_string_with_options(message, &PrintOptions::default())
+}