Upgrade rust/crates/protobuf-codegen to 2.17.0 am: ba676d3979 am: c300d33b99 am: 850ea9eeea am: f7b6f14c28 am: 5d91e0b145

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/protobuf-codegen/+/1398869

Change-Id: I00f268ec28b8d5deb66348302d06d3448d4758c8
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index f32bb3e..528d884 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
 {
   "git": {
-    "sha1": "ea76606acceb1aced6d4bc804d32360f3065e81b"
+    "sha1": "5e7854f82d19505a98ca22e0b83b79a0e6e90c2b"
   }
 }
diff --git a/Android.bp b/Android.bp
index a43a91a..b61ed21 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,6 +2,7 @@
 
 rust_library_host {
     name: "libprotobuf_codegen",
+    // has rustc warnings
     crate_name: "protobuf_codegen",
     srcs: ["src/lib.rs"],
     edition: "2015",
@@ -12,6 +13,7 @@
 
 rust_test_host {
     name: "protobuf-codegen_host_test_src_lib",
+    // has rustc warnings
     crate_name: "protobuf_codegen",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
@@ -24,6 +26,7 @@
 
 rust_binary_host {
     name: "protoc-gen-rust",
+    // has rustc warnings
     crate_name: "protoc_gen_rust",
     srcs: ["src/bin/protoc-gen-rust.rs"],
     edition: "2015",
@@ -34,4 +37,4 @@
 }
 
 // dependent_library ["feature_list"]
-//   protobuf-2.16.2
+//   protobuf-2.17.0
diff --git a/Cargo.lock b/Cargo.lock
index 9423014..91974a5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,13 +2,13 @@
 # It is not intended for manual editing.
 [[package]]
 name = "protobuf"
-version = "2.16.2"
+version = "2.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d883f78645c21b7281d21305181aa1f4dd9e9363e7cf2566c93121552cff003e"
+checksum = "cb14183cc7f213ee2410067e1ceeadba2a7478a59432ff0747a335202798b1e2"
 
 [[package]]
 name = "protobuf-codegen"
-version = "2.16.2"
+version = "2.17.0"
 dependencies = [
  "protobuf",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 0e82baa..4272db8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,7 +12,7 @@
 
 [package]
 name = "protobuf-codegen"
-version = "2.16.2"
+version = "2.17.0"
 authors = ["Stepan Koltsov <stepan.koltsov@gmail.com>"]
 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.16.2"
+version = "=2.17.0"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index ee9469d..3c3fe29 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "protobuf-codegen"
-version = "2.16.2"
+version = "2.17.0"
 authors = ["Stepan Koltsov <stepan.koltsov@gmail.com>"]
 license = "MIT"
 homepage = "https://github.com/stepancheg/rust-protobuf/"
@@ -17,7 +17,7 @@
 bench = false
 
 [dependencies]
-protobuf = { path = "../protobuf", version = "=2.16.2" }
+protobuf = { path = "../protobuf", version = "=2.17.0" }
 
 [[bin]]
 
diff --git a/METADATA b/METADATA
index c999301..bade869 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/stepancheg/rust-protobuf"
   }
-  version: "2.16.2"
+  version: "2.17.0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 7
-    day: 10
+    month: 8
+    day: 12
   }
 }
diff --git a/src/code_writer.rs b/src/code_writer.rs
index 9f3f3a0..8b53bc6 100644
--- a/src/code_writer.rs
+++ b/src/code_writer.rs
@@ -1,7 +1,9 @@
 // TODO: used by grpc-rust, should move it into separate crate.
 #![doc(hidden)]
 
+use inside::protobuf_crate_path;
 use std::io::Write;
+use Customize;
 
 /// Field visibility.
 pub enum Visibility {
@@ -102,29 +104,34 @@
         self.write_line(&format!("pub const {}: {} = {};", name, field_type, init));
     }
 
-    pub fn lazy_static(&mut self, name: &str, ty: &str) {
-        self.lazy_static_protobuf_path(name, ty, "::protobuf")
-    }
-
-    pub fn lazy_static_protobuf_path(&mut self, name: &str, ty: &str, protobuf_crate_path: &str) {
+    pub fn lazy_static(&mut self, name: &str, ty: &str, customize: &Customize) {
         self.write_line(&format!(
             "static {}: {}::rt::LazyV2<{}> = {}::rt::LazyV2::INIT;",
-            name, protobuf_crate_path, ty, protobuf_crate_path,
+            name,
+            protobuf_crate_path(customize),
+            ty,
+            protobuf_crate_path(customize),
         ));
     }
 
-    pub fn lazy_static_decl_get<F>(&mut self, name: &str, ty: &str, init: F)
+    pub fn lazy_static_decl_get<F>(&mut self, name: &str, ty: &str, customize: &Customize, init: F)
     where
         F: Fn(&mut CodeWriter),
     {
-        self.lazy_static(name, ty);
+        self.lazy_static(name, ty, customize);
         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);
+    pub fn lazy_static_decl_get_simple(
+        &mut self,
+        name: &str,
+        ty: &str,
+        init: &str,
+        customize: &Customize,
+    ) {
+        self.lazy_static(name, ty, customize);
         self.write_line(&format!("{}.get({})", name, init));
     }
 
diff --git a/src/enums.rs b/src/enums.rs
index 47ac49a..18dcbec 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -77,6 +77,7 @@
                 current_file,
                 false,
                 root_scope,
+                customize,
             )
             .to_string()
         };
@@ -206,76 +207,102 @@
 
     fn write_impl_enum(&self, w: &mut CodeWriter) {
         let ref type_name = self.type_name;
-        w.impl_for_block("::protobuf::ProtobufEnum", &type_name, |w| {
-            self.write_fn_value(w);
+        w.impl_for_block(
+            &format!("{}::ProtobufEnum", protobuf_crate_path(&self.customize)),
+            &format!("{}", type_name),
+            |w| {
+                self.write_fn_value(w);
 
-            w.write_line("");
-            let ref type_name = self.type_name;
-            w.def_fn(
-                &format!(
-                    "from_i32(value: i32) -> ::std::option::Option<{}>",
-                    type_name
-                ),
-                |w| {
-                    w.match_expr("value", |w| {
-                        let values = self.values_unique();
-                        for value in values {
-                            w.write_line(&format!(
-                                "{} => ::std::option::Option::Some({}),",
-                                value.number(),
-                                value.rust_name_outer()
-                            ));
-                        }
-                        w.write_line(&format!("_ => ::std::option::Option::None"));
-                    });
-                },
-            );
-
-            w.write_line("");
-            w.def_fn(&format!("values() -> &'static [Self]"), |w| {
-                w.write_line(&format!("static values: &'static [{}] = &[", type_name));
-                w.indented(|w| {
-                    for value in self.values_all() {
-                        w.write_line(&format!("{},", value.rust_name_outer()));
-                    }
-                });
-                w.write_line("];");
-                w.write_line("values");
-            });
-
-            if !self.lite_runtime {
                 w.write_line("");
+                let ref type_name = self.type_name;
                 w.def_fn(
                     &format!(
-                        "enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor"
+                        "from_i32(value: i32) -> ::std::option::Option<{}>",
+                        type_name
                     ),
                     |w| {
-                        w.lazy_static_decl_get(
-                            "descriptor",
-                            "::protobuf::reflect::EnumDescriptor",
-                            |w| {
-                                let ref type_name = self.type_name;
+                        w.match_expr("value", |w| {
+                            let values = self.values_unique();
+                            for value in values {
                                 w.write_line(&format!(
-                                    "::protobuf::reflect::EnumDescriptor::new_pb_name::<{}>(\"{}\", {})",
+                                    "{} => ::std::option::Option::Some({}),",
+                                    value.number(),
+                                    value.rust_name_outer()
+                                ));
+                            }
+                            w.write_line(&format!("_ => ::std::option::Option::None"));
+                        });
+                    },
+                );
+
+                w.write_line("");
+                w.def_fn(&format!("values() -> &'static [Self]"), |w| {
+                    w.write_line(&format!("static values: &'static [{}] = &[", type_name));
+                    w.indented(|w| {
+                        for value in self.values_all() {
+                            w.write_line(&format!("{},", value.rust_name_outer()));
+                        }
+                    });
+                    w.write_line("];");
+                    w.write_line("values");
+                });
+
+                if !self.lite_runtime {
+                    w.write_line("");
+                    w.def_fn(
+                        &format!(
+                            "enum_descriptor_static() -> &'static {}::reflect::EnumDescriptor",
+                            protobuf_crate_path(&self.customize)
+                        ),
+                        |w| {
+                            w.lazy_static_decl_get(
+                                "descriptor",
+                                &format!(
+                                    "{}::reflect::EnumDescriptor",
+                                    protobuf_crate_path(&self.customize)
+                                ),
+                                &self.customize,
+                                |w| {
+                                    let ref type_name = self.type_name;
+                                    w.write_line(&format!(
+                                    "{}::reflect::EnumDescriptor::new_pb_name::<{}>(\"{}\", {})",
+                                    protobuf_crate_path(&self.customize),
                                     type_name,
                                     self.enum_with_scope.name_to_package(),
                                     file_descriptor_proto_expr(&self.enum_with_scope.scope)
                                 ));
-                            },
-                        );
-                    },
-                );
-            }
-        });
+                                },
+                            );
+                        },
+                    );
+                }
+            },
+        );
     }
 
     fn write_impl_value(&self, w: &mut CodeWriter) {
-        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(::protobuf::ProtobufEnum::descriptor(self))"),
-            )
-        })
+        w.impl_for_block(
+            &format!(
+                "{}::reflect::ProtobufValue",
+                protobuf_crate_path(&self.customize)
+            ),
+            &format!("{}", self.type_name),
+            |w| {
+                w.def_fn(
+                    &format!(
+                        "as_ref(&self) -> {}::reflect::ReflectValueRef",
+                        protobuf_crate_path(&self.customize)
+                    ),
+                    |w| {
+                        w.write_line(&format!(
+                        "{}::reflect::ReflectValueRef::Enum({}::ProtobufEnum::descriptor(self))",
+                        protobuf_crate_path(&self.customize),
+                        protobuf_crate_path(&self.customize)
+                    ))
+                    },
+                )
+            },
+        )
     }
 
     fn write_impl_copy(&self, w: &mut CodeWriter) {
diff --git a/src/extensions.rs b/src/extensions.rs
index 637e18f..0740fdb 100644
--- a/src/extensions.rs
+++ b/src/extensions.rs
@@ -1,6 +1,7 @@
 use super::code_writer::CodeWriter;
 use super::rust_types_values::*;
 use field::rust_field_name_for_protobuf_field_name;
+use inside::protobuf_crate_path;
 use protobuf::descriptor::*;
 use protobuf_name::ProtobufAbsolutePath;
 use scope::RootScope;
@@ -20,6 +21,7 @@
             self.file,
             true,
             self.root_scope,
+            &self.customize,
         )
     }
 
@@ -40,6 +42,7 @@
                 self.file,
                 true,
                 self.root_scope,
+                &self.customize,
             );
             match self.field.get_field_type() {
                 FieldDescriptorProto_Type::TYPE_MESSAGE => {
@@ -59,7 +62,11 @@
         } else {
             "Optional"
         };
-        let field_type = format!("::protobuf::ext::ExtField{}", suffix);
+        let field_type = format!(
+            "{}::ext::ExtField{}",
+            protobuf_crate_path(&self.customize),
+            suffix
+        );
         w.pub_const(
             rust_field_name_for_protobuf_field_name(self.field.get_name()).get(),
             &format!(
diff --git a/src/field/mod.rs b/src/field/mod.rs
index 4925d2c..cbe99ee 100644
--- a/src/field/mod.rs
+++ b/src/field/mod.rs
@@ -322,6 +322,7 @@
             field.message.get_scope().file_scope.file_descriptor,
             false,
             root_scope,
+            customize,
         );
         match (field.field.get_field_type(), message_or_enum) {
             (
@@ -945,12 +946,14 @@
             None => match self.proto_type {
                 FieldDescriptorProto_Type::TYPE_MESSAGE => panic!("not a single-liner"),
                 FieldDescriptorProto_Type::TYPE_BYTES => format!(
-                    "::protobuf::rt::bytes_size({}, &{})",
+                    "{}::rt::bytes_size({}, &{})",
+                    protobuf_crate_path(&self.customize),
                     self.proto_field.number(),
                     var
                 ),
                 FieldDescriptorProto_Type::TYPE_STRING => format!(
-                    "::protobuf::rt::string_size({}, &{})",
+                    "{}::rt::string_size({}, &{})",
+                    protobuf_crate_path(&self.customize),
                     self.proto_field.number(),
                     var
                 ),
@@ -960,7 +963,8 @@
                         t => t.clone(),
                     };
                     format!(
-                        "::protobuf::rt::enum_size({}, {})",
+                        "{}::rt::enum_size({}, {})",
+                        protobuf_crate_path(&self.customize),
                         self.proto_field.number(),
                         var_type.into_target(&param_type, var, &self.customize)
                     )
@@ -972,16 +976,19 @@
                     };
                     if self.proto_type.is_s_varint() {
                         format!(
-                            "::protobuf::rt::value_varint_zigzag_size({}, {})",
+                            "{}::rt::value_varint_zigzag_size({}, {})",
+                            protobuf_crate_path(&self.customize),
                             self.proto_field.number(),
                             var_type.into_target(&param_type, var, &self.customize)
                         )
                     } else {
                         format!(
-                            "::protobuf::rt::value_size({}, {}, ::protobuf::wire_format::{:?})",
+                            "{}::rt::value_size({}, {}, {}::wire_format::{:?})",
+                            protobuf_crate_path(&self.customize),
                             self.proto_field.number(),
                             var_type.into_target(&param_type, var, &self.customize),
-                            self.wire_type
+                            protobuf_crate_path(&self.customize),
+                            self.wire_type,
                         )
                     }
                 }
@@ -998,9 +1005,10 @@
         match self.proto_type {
             FieldDescriptorProto_Type::TYPE_MESSAGE => {
                 w.write_line(&format!(
-                    "{}.write_tag({}, ::protobuf::wire_format::{:?})?;",
+                    "{}.write_tag({}, {}::wire_format::{:?})?;",
                     os,
                     self.proto_field.number(),
+                    protobuf_crate_path(&self.customize),
                     wire_format::WireTypeLengthDelimited
                 ));
                 w.write_line(&format!(
@@ -1179,7 +1187,10 @@
                 flag: SingularFieldFlag::WithFlag { .. },
                 ..
             } => {
-                self.write_self_field_assign(w, &full_storage_type.wrap_value(value));
+                self.write_self_field_assign(
+                    w,
+                    &full_storage_type.wrap_value(value, &self.customize),
+                );
             }
             &SingularField {
                 flag: SingularFieldFlag::WithoutFlag,
@@ -1201,7 +1212,8 @@
                 let wrapped = if *flag == SingularFieldFlag::WithoutFlag {
                     converted
                 } else {
-                    self.full_storage_type().wrap_value(&converted)
+                    self.full_storage_type()
+                        .wrap_value(&converted, &self.customize)
                 };
                 self.write_self_field_assign(w, &wrapped);
             }
@@ -1337,8 +1349,12 @@
         };
         let type_name_for_fn = protobuf_name(self.proto_type);
         w.write_line(&format!(
-            "::protobuf::rt::read_{}_{}{}_into(wire_type, is, &mut self.{})?;",
-            singular_or_repeated, carllerche, type_name_for_fn, self.rust_name
+            "{}::rt::read_{}_{}{}_into(wire_type, is, &mut self.{})?;",
+            protobuf_crate_path(&self.customize),
+            singular_or_repeated,
+            carllerche,
+            type_name_for_fn,
+            self.rust_name
         ));
     }
 
@@ -1353,8 +1369,10 @@
     fn write_assert_wire_type(&self, wire_type_var: &str, w: &mut CodeWriter) {
         w.if_stmt(
             &format!(
-                "{} != ::protobuf::wire_format::{:?}",
-                wire_type_var, self.wire_type
+                "{} != {}::wire_format::{:?}",
+                wire_type_var,
+                protobuf_crate_path(&self.customize),
+                self.wire_type
             ),
             |w| {
                 self.write_error_unexpected_wire_type(wire_type_var, w);
@@ -1394,7 +1412,8 @@
             ref key, ref value, ..
         } = self.map();
         w.write_line(&format!(
-            "::protobuf::rt::read_map_into::<{}, {}>(wire_type, is, &mut {})?;",
+            "{}::rt::read_map_into::<{}, {}>(wire_type, is, &mut {})?;",
+            protobuf_crate_path(&self.customize),
             key.lib_protobuf_type(&self.customize),
             value.lib_protobuf_type(&self.customize),
             self.self_field()
@@ -1420,7 +1439,8 @@
                     SingularFieldFlag::WithoutFlag => "proto3",
                 };
                 w.write_line(&format!(
-                    "::protobuf::rt::read_{}_enum_with_unknown_fields_into({}, is, &mut self.{}, {}, &mut self.unknown_fields)?",
+                    "{}::rt::read_{}_enum_with_unknown_fields_into({}, is, &mut self.{}, {}, &mut self.unknown_fields)?",
+                    protobuf_crate_path(&self.customize),
                     version,
                     wire_type_var,
                     self.rust_name,
@@ -1455,7 +1475,8 @@
             }
             FieldElem::Enum(..) => {
                 w.write_line(&format!(
-                    "::protobuf::rt::read_repeated_enum_with_unknown_fields_into({}, is, &mut self.{}, {}, &mut self.unknown_fields)?",
+                    "{}::rt::read_repeated_enum_with_unknown_fields_into({}, is, &mut self.{}, {}, &mut self.unknown_fields)?",
+                    protobuf_crate_path(&self.customize),
                     wire_type_var,
                     self.rust_name,
                     self.proto_field.number()
@@ -1513,8 +1534,10 @@
                 w.write_line(&format!("let len = {}.compute_size();", item_var));
                 let tag_size = self.tag_size();
                 w.write_line(&format!(
-                    "{} += {} + ::protobuf::rt::compute_raw_varint32_size(len) + len;",
-                    sum_var, tag_size
+                    "{} += {} + {}::rt::compute_raw_varint32_size(len) + len;",
+                    sum_var,
+                    tag_size,
+                    protobuf_crate_path(&self.customize)
                 ));
             }
             _ => {
@@ -1566,7 +1589,8 @@
                 ref key, ref value, ..
             }) => {
                 w.write_line(&format!(
-                    "::protobuf::rt::write_map_with_cached_sizes::<{}, {}>({}, &{}, os)?;",
+                    "{}::rt::write_map_with_cached_sizes::<{}, {}>({}, &{}, os)?;",
+                    protobuf_crate_path(&self.customize),
                     key.lib_protobuf_type(&self.customize),
                     value.lib_protobuf_type(&self.customize),
                     self.proto_field.number(),
diff --git a/src/file.rs b/src/file.rs
index 0c21d99..413e1bc 100644
--- a/src/file.rs
+++ b/src/file.rs
@@ -13,7 +13,7 @@
 }
 
 pub(crate) fn proto_path_to_rust_mod(path: &str) -> RustIdent {
-    let without_dir = strx::remove_to(path, '/');
+    let without_dir = strx::remove_to(path, std::path::is_separator);
     let without_suffix = strx::remove_suffix(without_dir, ".proto");
 
     let name = without_suffix
@@ -67,4 +67,21 @@
     fn test_mod_path_empty_ext() {
         assert_eq!(RustIdent::from("proto"), proto_path_to_rust_mod("proto"));
     }
+
+    #[test]
+    fn test_mod_path_dir() {
+        assert_eq!(
+            RustIdent::from("baz"),
+            proto_path_to_rust_mod("foo/bar/baz.proto"),
+        )
+    }
+
+    #[cfg(target_os = "windows")]
+    #[test]
+    fn test_mod_path_dir_backslashes() {
+        assert_eq!(
+            RustIdent::from("baz"),
+            proto_path_to_rust_mod("foo\\bar\\baz.proto"),
+        )
+    }
 }
diff --git a/src/inside.rs b/src/inside.rs
index 2590e9e..bbdcfdb 100644
--- a/src/inside.rs
+++ b/src/inside.rs
@@ -4,8 +4,7 @@
 /// used inside or outside of protobuf crate.
 pub(crate) fn protobuf_crate_path(customize: &Customize) -> &str {
     match customize.inside_protobuf {
-        // Can't use `crate::` paths before Rust 1.32.0
-        //Some(true) => "crate",
+        Some(true) => "crate",
         _ => "::protobuf",
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index e65c1bd..4fc3ee9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,7 +12,7 @@
 //! * `protoc-rust` crate (codegen which depends on `protoc` binary for parsing)
 //! * `protobuf-codegen-pure` crate
 
-#![deny(intra_doc_link_resolution_failure)]
+#![deny(broken_intra_doc_links)]
 #![deny(missing_docs)]
 
 extern crate protobuf;
@@ -66,6 +66,13 @@
 use scope::FileScope;
 use scope::RootScope;
 
+#[doc(hidden)]
+pub use protobuf_name::ProtobufAbsolutePath;
+#[doc(hidden)]
+pub use protobuf_name::ProtobufIdent;
+#[doc(hidden)]
+pub use protobuf_name::ProtobufRelativePath;
+
 fn escape_byte(s: &mut String, b: u8) {
     if b == b'\n' {
         write!(s, "\\n").unwrap();
@@ -120,24 +127,33 @@
     });
     w.write_line("\";");
     w.write_line("");
-    w.lazy_static_protobuf_path(
+    w.lazy_static(
         "file_descriptor_proto_lazy",
         &format!(
             "{}::descriptor::FileDescriptorProto",
             protobuf_crate_path(customize)
         ),
-        protobuf_crate_path(customize),
+        customize,
     );
     w.write_line("");
     w.def_fn(
-        "parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto",
+        &format!(
+            "parse_descriptor_proto() -> {}::descriptor::FileDescriptorProto",
+            protobuf_crate_path(customize)
+        ),
         |w| {
-            w.write_line("::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()");
+            w.write_line(&format!(
+                "{}::parse_from_bytes(file_descriptor_proto_data).unwrap()",
+                protobuf_crate_path(customize)
+            ));
         },
     );
     w.write_line("");
     w.pub_fn(
-        "file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto",
+        &format!(
+            "file_descriptor_proto() -> &'static {}::descriptor::FileDescriptorProto",
+            protobuf_crate_path(customize)
+        ),
         |w| {
             w.block("file_descriptor_proto_lazy.get(|| {", "})", |w| {
                 w.write_line("parse_descriptor_proto()");
@@ -170,9 +186,9 @@
     {
         let mut w = CodeWriter::new(&mut v);
 
-        // Hack: hard code version number here because Android.bp
+        // ANDROID: hard code version number here because Android.bp
         // rust modules cannot pass it though env variable yet.
-        w.write_generated_by("rust-protobuf", "2.16.2");
+        w.write_generated_by("rust-protobuf", "2.17.0");
         w.write_line(&format!("//! Generated file from `{}`", file.get_name()));
         if customize.inside_protobuf != Some(true) {
             w.write_line("");
@@ -269,3 +285,9 @@
         gen(r.file_descriptors, r.files_to_generate, &customize)
     });
 }
+
+/// Used in protobuf-codegen-identical-test
+#[doc(hidden)]
+pub fn proto_name_to_rs(name: &str) -> String {
+    format!("{}.rs", proto_path_to_rust_mod(name))
+}
diff --git a/src/message.rs b/src/message.rs
index 00b9ad6..e39ff36 100644
--- a/src/message.rs
+++ b/src/message.rs
@@ -188,6 +188,7 @@
                     "instance",
                     &self.type_name.to_string(),
                     &format!("{}::new", self.type_name),
+                    &self.customize,
                 );
             },
         );
@@ -241,14 +242,20 @@
 
     fn write_unknown_fields(&self, w: &mut CodeWriter) {
         w.def_fn(
-            "get_unknown_fields(&self) -> &::protobuf::UnknownFields",
+            &format!(
+                "get_unknown_fields(&self) -> &{}::UnknownFields",
+                protobuf_crate_path(&self.customize)
+            ),
             |w| {
                 w.write_line("&self.unknown_fields");
             },
         );
         w.write_line("");
         w.def_fn(
-            "mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields",
+            &format!(
+                "mut_unknown_fields(&mut self) -> &mut {}::UnknownFields",
+                protobuf_crate_path(&self.customize)
+            ),
             |w| {
                 w.write_line("&mut self.unknown_fields");
             },
@@ -283,8 +290,9 @@
     fn write_descriptor_field(&self, fields_var: &str, field: &FieldGen, w: &mut CodeWriter) {
         let accessor_fn = field.accessor_fn();
         w.write_line(&format!(
-            "{}.push(::protobuf::reflect::accessor::{}(",
+            "{}.push({}::reflect::accessor::{}(",
             fields_var,
+            protobuf_crate_path(&self.customize),
             accessor_fn.sig()
         ));
         w.indented(|w| {
@@ -311,11 +319,18 @@
 
     fn write_descriptor_static(&self, w: &mut CodeWriter) {
         w.def_fn(
-            &format!("descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor"),
+            &format!(
+                "descriptor_static() -> &'static {}::reflect::MessageDescriptor",
+                protobuf_crate_path(&self.customize)
+            ),
             |w| {
                 w.lazy_static_decl_get(
                     "descriptor",
-                    "::protobuf::reflect::MessageDescriptor",
+                    &format!(
+                        "{}::reflect::MessageDescriptor",
+                        protobuf_crate_path(&self.customize)
+                    ),
+                    &self.customize,
                     |w| {
                         let fields = self.fields_except_group();
                         if fields.is_empty() {
@@ -327,7 +342,8 @@
                             self.write_descriptor_field("fields", field, w);
                         }
                         w.write_line(&format!(
-                            "::protobuf::reflect::MessageDescriptor::new_pb_name::<{}>(",
+                            "{}::reflect::MessageDescriptor::new_pb_name::<{}>(",
+                            protobuf_crate_path(&self.customize),
                             self.type_name
                         ));
                         w.indented(|w| {
@@ -372,7 +388,9 @@
     }
 
     fn write_impl_message(&self, w: &mut CodeWriter) {
-        w.impl_for_block("::protobuf::Message", &self.type_name.to_string(), |w| {
+        w.impl_for_block(
+            &format!("{}::Message", protobuf_crate_path(&self.customize)),
+            &self.type_name.to_string(), |w| {
             self.write_is_initialized(w);
             w.write_line("");
             self.write_merge_from(w);
@@ -399,7 +417,7 @@
             );
             w.write_line("");
             w.def_fn(
-                "descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor",
+                &format!("descriptor(&self) -> &'static {}::reflect::MessageDescriptor", protobuf_crate_path(&self.customize)),
                 |w| {
                     w.write_line("Self::descriptor_static()");
                 },
@@ -419,12 +437,23 @@
 
     fn write_impl_value(&self, w: &mut CodeWriter) {
         w.impl_for_block(
-            "::protobuf::reflect::ProtobufValue",
+            &format!(
+                "{}::reflect::ProtobufValue",
+                protobuf_crate_path(&self.customize)
+            ),
             &self.type_name.to_string(),
             |w| {
                 w.def_fn(
-                    "as_ref(&self) -> ::protobuf::reflect::ReflectValueRef",
-                    |w| w.write_line("::protobuf::reflect::ReflectValueRef::Message(self)"),
+                    &format!(
+                        "as_ref(&self) -> {}::reflect::ReflectValueRef",
+                        protobuf_crate_path(&self.customize)
+                    ),
+                    |w| {
+                        w.write_line(&format!(
+                            "{}::reflect::ReflectValueRef::Message(self)",
+                            protobuf_crate_path(&self.customize)
+                        ))
+                    },
                 )
             },
         )
@@ -435,21 +464,28 @@
             w.def_fn(
                 "fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result",
                 |w| {
-                    w.write_line("::protobuf::text_format::fmt(self, f)");
+                    w.write_line(&format!(
+                        "{}::text_format::fmt(self, f)",
+                        protobuf_crate_path(&self.customize)
+                    ));
                 },
             );
         });
     }
 
     fn write_impl_clear(&self, w: &mut CodeWriter) {
-        w.impl_for_block("::protobuf::Clear", &self.type_name.to_string(), |w| {
-            w.def_fn("clear(&mut self)", |w| {
-                for f in self.fields_except_group() {
-                    f.write_clear(w);
-                }
-                w.write_line("self.unknown_fields.clear();");
-            });
-        });
+        w.impl_for_block(
+            &format!("{}::Clear", protobuf_crate_path(&self.customize)),
+            &format!("{}", self.type_name),
+            |w| {
+                w.def_fn("clear(&mut self)", |w| {
+                    for f in self.fields_except_group() {
+                        f.write_clear(w);
+                    }
+                    w.write_line("self.unknown_fields.clear();");
+                });
+            },
+        );
     }
 
     #[allow(dead_code)]
diff --git a/src/protobuf_name.rs b/src/protobuf_name.rs
index c219394..03163e3 100644
--- a/src/protobuf_name.rs
+++ b/src/protobuf_name.rs
@@ -5,6 +5,7 @@
 pub struct ProtobufIdent(String);
 
 impl ProtobufIdent {
+    /// New ident from a string.
     #[allow(dead_code)]
     pub fn new(s: &str) -> ProtobufIdent {
         assert!(!s.is_empty());
@@ -14,6 +15,7 @@
         ProtobufIdent(s.to_owned())
     }
 
+    /// Get as a string.
     pub fn get(&self) -> &str {
         &self.0
     }
@@ -37,36 +39,44 @@
     }
 }
 
+/// Relative protobuf identifier path.
 #[derive(Debug, Eq, PartialEq, Clone)]
 pub struct ProtobufRelativePath {
+    /// The path
     pub path: String,
 }
 
 #[allow(dead_code)]
 impl ProtobufRelativePath {
+    /// Empty relative path.
     pub fn empty() -> ProtobufRelativePath {
         ProtobufRelativePath::new(String::new())
     }
 
+    /// New path from a string.
     pub fn new(path: String) -> ProtobufRelativePath {
         assert!(!path.starts_with("."));
 
         ProtobufRelativePath { path }
     }
 
+    /// From path components.
     pub fn from_components<I: IntoIterator<Item = ProtobufIdent>>(i: I) -> ProtobufRelativePath {
         let v: Vec<String> = i.into_iter().map(|c| c.get().to_owned()).collect();
         ProtobufRelativePath::from(v.join("."))
     }
 
+    /// Get the string.
     pub fn get(&self) -> &str {
         &self.path
     }
 
+    /// The path is empty.
     pub fn is_empty(&self) -> bool {
         self.path.is_empty()
     }
 
+    /// As absolute path from root namespace.
     pub fn into_absolute(self) -> ProtobufAbsolutePath {
         if self.is_empty() {
             ProtobufAbsolutePath::root()
@@ -101,6 +111,7 @@
         }
     }
 
+    /// Self path and parent paths.
     pub fn self_and_parents(&self) -> Vec<ProtobufRelativePath> {
         let mut tmp = self.clone();
 
@@ -116,6 +127,7 @@
         r
     }
 
+    /// Append path component.
     pub fn append(&self, simple: &ProtobufRelativePath) -> ProtobufRelativePath {
         if self.path.is_empty() {
             ProtobufRelativePath::from(simple.get())
@@ -124,10 +136,12 @@
         }
     }
 
+    /// Append identifier to the path.
     pub fn append_ident(&self, simple: &ProtobufIdent) -> ProtobufRelativePath {
         self.append(&ProtobufRelativePath::from(simple.clone()))
     }
 
+    /// Get first component path and remaining.
     pub fn split_first_rem(&self) -> Option<(ProtobufIdent, ProtobufRelativePath)> {
         if self.is_empty() {
             None
@@ -215,8 +229,12 @@
     }
 }
 
+/// Absolute protobuf path (e. g. package).
+///
+/// This is not filesystem path.
 #[derive(Clone, Eq, PartialEq, Debug, Hash)]
 pub struct ProtobufAbsolutePath {
+    /// The path.
     pub path: String,
 }
 
@@ -225,16 +243,21 @@
         ProtobufAbsolutePath::new(String::new())
     }
 
+    /// From string.
     pub fn new(path: String) -> ProtobufAbsolutePath {
         assert!(path.is_empty() || path.starts_with("."), path);
         assert!(!path.ends_with("."), path);
         ProtobufAbsolutePath { path }
     }
 
+    /// The path is empty.
     pub fn is_empty(&self) -> bool {
         self.path.is_empty()
     }
 
+    /// From a path without leading dot.
+    ///
+    /// (Protobuf paths start with dot).
     pub fn from_path_without_dot(path: &str) -> ProtobufAbsolutePath {
         if path.is_empty() {
             ProtobufAbsolutePath::root()
@@ -245,7 +268,16 @@
         }
     }
 
+    /// Parse absolute path.
     #[allow(dead_code)]
+    pub fn from_package_path(path: Option<&str>) -> ProtobufAbsolutePath {
+        match path {
+            None => ProtobufAbsolutePath::root(),
+            Some(path) => ProtobufAbsolutePath::from_path_without_dot(path),
+        }
+    }
+
+    /// Construct abs path from a string which may start with a dot.
     pub fn from_path_maybe_dot(path: &str) -> ProtobufAbsolutePath {
         if path.starts_with(".") {
             ProtobufAbsolutePath::new(path.to_owned())
@@ -254,11 +286,13 @@
         }
     }
 
+    /// Push identifier to the path.
     pub fn push_simple(&mut self, simple: ProtobufIdent) {
         self.path.push('.');
         self.path.push_str(simple.get());
     }
 
+    /// Push relative path.
     pub fn push_relative(&mut self, relative: &ProtobufRelativePath) {
         if !relative.is_empty() {
             self.path.push('.');
@@ -266,6 +300,7 @@
         }
     }
 
+    /// Try remove a prefix.
     pub fn remove_prefix(&self, prefix: &ProtobufAbsolutePath) -> Option<ProtobufRelativePath> {
         if self.path.starts_with(&prefix.path) {
             let rem = &self.path[prefix.path.len()..];
diff --git a/src/rust_types_values.rs b/src/rust_types_values.rs
index 1134775..9660062 100644
--- a/src/rust_types_values.rs
+++ b/src/rust_types_values.rs
@@ -226,7 +226,11 @@
             | RustType::SingularField(..)
             | RustType::SingularPtrField(..)
             | RustType::HashMap(..) => format!("{}.clear()", v),
-            RustType::Chars => format!("::protobuf::Clear::clear(&mut {})", v),
+            RustType::Chars => format!(
+                "{}::Clear::clear(&mut {})",
+                protobuf_crate_path(customize),
+                v
+            ),
             RustType::Bool | RustType::Float(..) | RustType::Int(..) | RustType::Enum(..) => {
                 format!("{} = {}", v, self.default_value(customize))
             }
@@ -235,13 +239,19 @@
     }
 
     // wrap value in storage type
-    pub fn wrap_value(&self, value: &str) -> String {
+    pub fn wrap_value(&self, value: &str, customize: &Customize) -> String {
         match *self {
             RustType::Option(..) => format!("::std::option::Option::Some({})", value),
-            RustType::SingularField(..) => format!("::protobuf::SingularField::some({})", value),
-            RustType::SingularPtrField(..) => {
-                format!("::protobuf::SingularPtrField::some({})", value)
-            }
+            RustType::SingularField(..) => format!(
+                "{}::SingularField::some({})",
+                protobuf_crate_path(customize),
+                value
+            ),
+            RustType::SingularPtrField(..) => format!(
+                "{}::SingularPtrField::some({})",
+                protobuf_crate_path(customize),
+                value
+            ),
             _ => panic!("not a wrapper type: {:?}", *self),
         }
     }
@@ -492,6 +502,7 @@
     file: &FileDescriptorProto,
     subm: bool,
     root_scope: &RootScope,
+    customize: &Customize,
 ) -> String {
     let message_or_enum = root_scope.find_message_or_enum(type_name);
     if message_or_enum.get_scope().get_file_descriptor().get_name() == file.get_name() {
@@ -504,11 +515,16 @@
     } else if let Some(name) = is_well_known_type_full(&type_name.path) {
         // Well-known types are included in rust-protobuf library
         // https://developers.google.com/protocol-buffers/docs/reference/google.protobuf
-        format!("::protobuf::well_known_types::{}", name)
+        format!(
+            "{}::well_known_types::{}",
+            protobuf_crate_path(customize),
+            name
+        )
     } else if is_descriptor_proto(message_or_enum.get_file_descriptor()) {
         // Messages defined in descriptor.proto
         format!(
-            "::protobuf::descriptor::{}",
+            "{}::descriptor::{}",
+            protobuf_crate_path(customize),
             message_or_enum.name_to_package()
         )
     } else {
@@ -542,7 +558,8 @@
     pub fn rust_type(&self, customize: &Customize) -> String {
         match self {
             &ProtobufTypeGen::Primitive(t, PrimitiveTypeVariant::Default) => format!(
-                "::protobuf::types::ProtobufType{}",
+                "{}::types::ProtobufType{}",
+                protobuf_crate_path(customize),
                 capitalize(protobuf_name(t))
             ),
             &ProtobufTypeGen::Primitive(
@@ -565,9 +582,11 @@
                 protobuf_crate_path(customize),
                 name
             ),
-            &ProtobufTypeGen::Enum(ref name) => {
-                format!("::protobuf::types::ProtobufTypeEnum<{}>", name)
-            }
+            &ProtobufTypeGen::Enum(ref name) => format!(
+                "{}::types::ProtobufTypeEnum<{}>",
+                protobuf_crate_path(customize),
+                name
+            ),
         }
     }
 }
diff --git a/src/strx.rs b/src/strx.rs
index e822bf8..d1b26fa 100644
--- a/src/strx.rs
+++ b/src/strx.rs
@@ -1,5 +1,8 @@
-pub fn remove_to<'s>(s: &'s str, c: char) -> &'s str {
-    match s.rfind(c) {
+pub fn remove_to<'s, P>(s: &'s str, pattern: P) -> &'s str
+where
+    P: Fn(char) -> bool,
+{
+    match s.rfind(pattern) {
         Some(pos) => &s[(pos + 1)..],
         None => s,
     }
@@ -34,9 +37,9 @@
 
     #[test]
     fn test_remove_to() {
-        assert_eq!("aaa", remove_to("aaa", '.'));
-        assert_eq!("bbb", remove_to("aaa.bbb", '.'));
-        assert_eq!("ccc", remove_to("aaa.bbb.ccc", '.'));
+        assert_eq!("aaa", remove_to("aaa", |c| c == '.'));
+        assert_eq!("bbb", remove_to("aaa.bbb", |c| c == '.'));
+        assert_eq!("ccc", remove_to("aaa.bbb.ccc", |c| c == '.'));
     }
 
     #[test]