Upgrade rust/crates/protobuf-codegen to 2.16.2

Test: make
Change-Id: I14166e5bd65e98c7c7a53cff992df72164346bc5
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index d6337d5..f32bb3e 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "09cb48471825c36fc5c8205f197eefbf664a10f7"
+    "sha1": "ea76606acceb1aced6d4bc804d32360f3065e81b"
   }
 }
diff --git a/Cargo.lock b/Cargo.lock
index b9bafb0..9423014 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,13 +2,13 @@
 # It is not intended for manual editing.
 [[package]]
 name = "protobuf"
-version = "2.14.0"
+version = "2.16.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485"
+checksum = "d883f78645c21b7281d21305181aa1f4dd9e9363e7cf2566c93121552cff003e"
 
 [[package]]
 name = "protobuf-codegen"
-version = "2.14.0"
+version = "2.16.2"
 dependencies = [
  "protobuf",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index afcb5be..0e82baa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
 
 [package]
 name = "protobuf-codegen"
-version = "2.14.0"
+version = "2.16.2"
 authors = ["Stepan Koltsov <[email protected]>"]
 description = "Code generator for rust-protobuf.\n\nIncludes a library and `protoc-gen-rust` binary.\n\nSee `protoc-rust` and `protobuf-codegen-pure` crates.\n"
 homepage = "https://github.com/stepancheg/rust-protobuf/"
@@ -34,4 +34,4 @@
 path = "src/bin/protobuf-bin-gen-rust-do-not-use.rs"
 test = false
 [dependencies.protobuf]
-version = "=2.14.0"
+version = "=2.16.2"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 0511478..ee9469d 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "protobuf-codegen"
-version = "2.14.0"
+version = "2.16.2"
 authors = ["Stepan Koltsov <[email protected]>"]
 license = "MIT"
 homepage = "https://github.com/stepancheg/rust-protobuf/"
@@ -17,7 +17,7 @@
 bench = false
 
 [dependencies]
-protobuf = { path = "../protobuf", version = "=2.14.0" }
+protobuf = { path = "../protobuf", version = "=2.16.2" }
 
 [[bin]]
 
diff --git a/METADATA b/METADATA
index 94eb560..c999301 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/stepancheg/rust-protobuf"
   }
-  version: "2.14.0"
+  version: "2.16.2"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 6
-    day: 3
+    month: 7
+    day: 10
   }
 }
diff --git a/README.android b/README.android
index 93d2ac7..a75eb35 100644
--- a/README.android
+++ b/README.android
@@ -8,7 +8,7 @@
 
         // Hack: hard code version number here because Android.bp
         // rust modules cannot pass it though env variable yet.
-        w.write_generated_by("rust-protobuf", "2.14.0");
+        w.write_generated_by("rust-protobuf", "2.16.2");
 
 If there are non-trivial changes in build.rs or src/lib.rs,
 please rerun cargo2android.py and verify the differences in
diff --git a/src/code_writer.rs b/src/code_writer.rs
index 61ce92f..9f3f3a0 100644
--- a/src/code_writer.rs
+++ b/src/code_writer.rs
@@ -55,7 +55,8 @@
         self.write_line("#![allow(unknown_lints)]");
         self.write_line("#![allow(clippy::all)]");
         self.write_line("");
-        self.write_line("#![cfg_attr(rustfmt, rustfmt_skip)]");
+        self.write_line("#![allow(unused_attributes)]");
+        self.write_line("#![rustfmt::skip]");
         self.write_line("");
         self.write_line("#![allow(box_pointers)]");
         self.write_line("#![allow(dead_code)]");
@@ -64,7 +65,6 @@
         self.write_line("#![allow(non_snake_case)]");
         self.write_line("#![allow(non_upper_case_globals)]");
         self.write_line("#![allow(trivial_casts)]");
-        self.write_line("#![allow(unsafe_code)]");
         self.write_line("#![allow(unused_imports)]");
         self.write_line("#![allow(unused_results)]");
     }
@@ -108,7 +108,7 @@
 
     pub fn lazy_static_protobuf_path(&mut self, name: &str, ty: &str, protobuf_crate_path: &str) {
         self.write_line(&format!(
-            "static mut {}: {}::lazy::Lazy<{}> = {}::lazy::Lazy::INIT;",
+            "static {}: {}::rt::LazyV2<{}> = {}::rt::LazyV2::INIT;",
             name, protobuf_crate_path, ty, protobuf_crate_path,
         ));
     }
@@ -118,18 +118,14 @@
         F: Fn(&mut CodeWriter),
     {
         self.lazy_static(name, ty);
-        self.unsafe_expr(|w| {
-            w.write_line(&format!("{}.get(|| {{", name));
-            w.indented(|w| init(w));
-            w.write_line(&format!("}})"));
-        });
+        self.write_line(&format!("{}.get(|| {{", name));
+        self.indented(|w| init(w));
+        self.write_line(&format!("}})"));
     }
 
     pub fn lazy_static_decl_get_simple(&mut self, name: &str, ty: &str, init: &str) {
         self.lazy_static(name, ty);
-        self.unsafe_expr(|w| {
-            w.write_line(&format!("{}.get({})", name, init));
-        });
+        self.write_line(&format!("{}.get({})", name, init));
     }
 
     pub fn block<F>(&mut self, first_line: &str, last_line: &str, cb: F)
diff --git a/src/enums.rs b/src/enums.rs
index 2c60f0c..47ac49a 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -5,6 +5,7 @@
 use super::code_writer::*;
 use super::customize::Customize;
 use file_descriptor::file_descriptor_proto_expr;
+use inside::protobuf_crate_path;
 use protobuf_name::ProtobufAbsolutePath;
 use rust_types_values::type_name_to_rust_relative;
 use scope::EnumWithScope;
@@ -272,7 +273,7 @@
         w.impl_for_block("::protobuf::reflect::ProtobufValue", &self.type_name, |w| {
             w.def_fn(
                 "as_ref(&self) -> ::protobuf::reflect::ReflectValueRef",
-                |w| w.write_line("::protobuf::reflect::ReflectValueRef::Enum(self.descriptor())"),
+                |w| w.write_line("::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self))"),
             )
         })
     }
@@ -283,18 +284,29 @@
 
     fn write_impl_eq(&self, w: &mut CodeWriter) {
         assert!(self.allow_alias());
-        w.impl_for_block("::std::cmp::PartialEq", &self.type_name, |w| {
-            w.def_fn("eq(&self, other: &Self) -> bool", |w| {
-                w.write_line("self.value() == other.value()");
-            });
-        });
+        w.impl_for_block(
+            "::std::cmp::PartialEq",
+            &format!("{}", self.type_name),
+            |w| {
+                w.def_fn("eq(&self, other: &Self) -> bool", |w| {
+                    w.write_line(&format!(
+                        "{}::ProtobufEnum::value(self) == {}::ProtobufEnum::value(other)",
+                        protobuf_crate_path(&self.customize),
+                        protobuf_crate_path(&self.customize)
+                    ));
+                });
+            },
+        );
     }
 
     fn write_impl_hash(&self, w: &mut CodeWriter) {
         assert!(self.allow_alias());
-        w.impl_for_block("::std::hash::Hash", &self.type_name, |w| {
+        w.impl_for_block("::std::hash::Hash", &format!("{}", self.type_name), |w| {
             w.def_fn("hash<H : ::std::hash::Hasher>(&self, state: &mut H)", |w| {
-                w.write_line("state.write_i32(self.value())");
+                w.write_line(&format!(
+                    "state.write_i32({}::ProtobufEnum::value(self))",
+                    protobuf_crate_path(&self.customize)
+                ));
             });
         });
     }
diff --git a/src/extensions.rs b/src/extensions.rs
index a3f8901..637e18f 100644
--- a/src/extensions.rs
+++ b/src/extensions.rs
@@ -88,9 +88,8 @@
     }
 
     w.write_line("");
+    w.write_line("/// Extension fields");
     w.pub_mod("exts", |w| {
-        w.write_line("use protobuf::Message as Message_imported_for_functions;");
-
         for field in file.get_extension() {
             if field.get_field_type() == FieldDescriptorProto_Type::TYPE_GROUP {
                 continue;
diff --git a/src/field/mod.rs b/src/field/mod.rs
index 37d4fe3..4925d2c 100644
--- a/src/field/mod.rs
+++ b/src/field/mod.rs
@@ -14,8 +14,10 @@
 
 use float;
 use inside::protobuf_crate_path;
+use message::RustTypeMessage;
 use protobuf_name::ProtobufAbsolutePath;
 use rust_name::RustIdent;
+use rust_name::RustIdentWithPath;
 use scope::FieldWithContext;
 use scope::MessageOrEnumWithScope;
 use scope::RootScope;
@@ -267,7 +269,9 @@
             ) => RustType::Bytes,
             FieldElem::Primitive(.., PrimitiveTypeVariant::Carllerche) => unreachable!(),
             FieldElem::Group => RustType::Group,
-            FieldElem::Message(ref name, ..) => RustType::Message(name.clone()),
+            FieldElem::Message(ref name, ..) => {
+                RustType::Message(RustTypeMessage(RustIdentWithPath::new(name.clone())))
+            }
             FieldElem::Enum(ref name, _, ref default_value) => {
                 RustType::Enum(name.clone(), default_value.clone())
             }
@@ -452,8 +456,13 @@
 
         let generate_accessors = customize.generate_accessors.unwrap_or(true);
 
-        let default_expose_field =
-            field.message.scope.file_scope.syntax() == Syntax::PROTO3 || !generate_accessors;
+        let syntax = field.message.scope.file_scope.syntax();
+
+        let field_may_have_custom_default_value = syntax == Syntax::PROTO2
+            && field.field.get_label() != FieldDescriptorProto_Label::LABEL_REPEATED
+            && field.field.get_field_type() != FieldDescriptorProto_Type::TYPE_MESSAGE;
+
+        let default_expose_field = !field_may_have_custom_default_value;
 
         let expose_field = customize.expose_fields.unwrap_or(default_expose_field);
 
@@ -1630,11 +1639,14 @@
 
         if self.proto_type == FieldDescriptorProto_Type::TYPE_MESSAGE {
             let self_field = self.self_field();
-            let ref field_type_name = self.elem().rust_storage_type();
+            let ref rust_type_message = match self.elem().rust_storage_type() {
+                RustType::Message(m) => m,
+                _ => unreachable!(),
+            };
             w.write_line(&format!(
-                "{}.as_ref().unwrap_or_else(|| {}::default_instance())",
+                "{}.as_ref().unwrap_or_else(|| {})",
                 self_field,
-                field_type_name.to_code(&self.customize)
+                rust_type_message.default_instance(&self.customize)
             ));
         } else {
             let get_xxx_default_value_rust = self.get_xxx_default_value_rust();
diff --git a/src/lib.rs b/src/lib.rs
index 1f91285..e65c1bd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -139,10 +139,8 @@
     w.pub_fn(
         "file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto",
         |w| {
-            w.unsafe_expr(|w| {
-                w.block("file_descriptor_proto_lazy.get(|| {", "})", |w| {
-                    w.write_line("parse_descriptor_proto()");
-                });
+            w.block("file_descriptor_proto_lazy.get(|| {", "})", |w| {
+                w.write_line("parse_descriptor_proto()");
             });
         },
     );
@@ -174,12 +172,8 @@
 
         // Hack: hard code version number here because Android.bp
         // rust modules cannot pass it though env variable yet.
-        w.write_generated_by("rust-protobuf", "2.14.0");
+        w.write_generated_by("rust-protobuf", "2.16.2");
         w.write_line(&format!("//! Generated file from `{}`", file.get_name()));
-
-        w.write_line("");
-        w.write_line("use protobuf::Message as Message_imported_for_functions;");
-        w.write_line("use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;");
         if customize.inside_protobuf != Some(true) {
             w.write_line("");
             w.write_line("/// Generated files are compatible only with the same version");
diff --git a/src/message.rs b/src/message.rs
index 5be3e5f..00b9ad6 100644
--- a/src/message.rs
+++ b/src/message.rs
@@ -15,6 +15,29 @@
 use scope::WithScope;
 use serde;
 
+use std::fmt;
+
+/// Protobuf message Rust type name
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub(crate) struct RustTypeMessage(pub RustIdentWithPath);
+
+impl fmt::Display for RustTypeMessage {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.0, f)
+    }
+}
+
+impl RustTypeMessage {
+    /// Code which emits default instance.
+    pub fn default_instance(&self, customize: &Customize) -> String {
+        format!(
+            "<{} as {}::Message>::default_instance()",
+            self.0,
+            protobuf_crate_path(customize)
+        )
+    }
+}
+
 /// Message info for codegen
 pub(crate) struct MessageGen<'a> {
     pub message: &'a MessageWithScope<'a>,
@@ -369,7 +392,7 @@
                 w.write_line("self as &mut dyn (::std::any::Any)");
             });
             w.def_fn(
-                "into_any(self: Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)>",
+                "into_any(self: ::std::boxed::Box<Self>) -> ::std::boxed::Box<dyn (::std::any::Any)>",
                 |w| {
                     w.write_line("self");
                 },
diff --git a/src/rust_types_values.rs b/src/rust_types_values.rs
index 7f32eec..1134775 100644
--- a/src/rust_types_values.rs
+++ b/src/rust_types_values.rs
@@ -2,6 +2,7 @@
 
 use super::well_known_types::is_well_known_type_full;
 use inside::protobuf_crate_path;
+use message::RustTypeMessage;
 use protobuf::descriptor::*;
 use protobuf_name::ProtobufAbsolutePath;
 use rust_name::RustIdent;
@@ -34,7 +35,7 @@
     // &T
     Ref(Box<RustType>),
     // protobuf message
-    Message(String),
+    Message(RustTypeMessage),
     // protobuf enum, not any enum
     Enum(String, RustIdent),
     // oneof enum
@@ -84,9 +85,8 @@
             ),
             RustType::Uniq(ref param) => format!("::std::boxed::Box<{}>", param.to_code(customize)),
             RustType::Ref(ref param) => format!("&{}", param.to_code(customize)),
-            RustType::Message(ref name)
-            | RustType::Enum(ref name, _)
-            | RustType::Oneof(ref name) => format!("{}", name),
+            RustType::Message(ref name) => format!("{}", name),
+            RustType::Enum(ref name, _) | RustType::Oneof(ref name) => format!("{}", name),
             RustType::Group => format!("<group>"),
             RustType::Bytes => format!("::bytes::Bytes"),
             RustType::Chars => format!("{}::Chars", protobuf_crate_path(customize)),
@@ -199,7 +199,7 @@
             }
             RustType::Message(ref name) => format!("{}::new()", name),
             RustType::Ref(ref m) if m.is_message() => match **m {
-                RustType::Message(ref name) => format!("{}::default_instance()", name),
+                RustType::Message(ref name) => name.default_instance(customize),
                 _ => unreachable!(),
             },
             // Note: default value of enum type may not be equal to default value of field
@@ -333,9 +333,19 @@
             {
                 return Ok(format!("&{}", v))
             }
-            (&RustType::Enum(..), &RustType::Int(true, 32)) => return Ok(format!("{}.value()", v)),
+            (&RustType::Enum(..), &RustType::Int(true, 32)) => {
+                return Ok(format!(
+                    "{}::ProtobufEnum::value(&{})",
+                    protobuf_crate_path(customize),
+                    v
+                ))
+            }
             (&RustType::Ref(ref t), &RustType::Int(true, 32)) if t.is_enum() => {
-                return Ok(format!("{}.value()", v))
+                return Ok(format!(
+                    "{}::ProtobufEnum::value({})",
+                    protobuf_crate_path(customize),
+                    v
+                ))
             }
             _ => (),
         };