Upgrade rust/crates/protobuf to 2.17.0

* Android.bp was regenerated. New rustc warnings were found.
* Keep local change in src/lib.rs to include out/version.rs.
* Update out/version.rs to the new version.

Change-Id: I9c2f7d412dcd42fe3769505629e05ab949300fe6
Test: make
diff --git a/src/reflect/acc/mod.rs b/src/reflect/acc/mod.rs
new file mode 100644
index 0000000..288c183
--- /dev/null
+++ b/src/reflect/acc/mod.rs
@@ -0,0 +1,31 @@
+#![doc(hidden)]
+
+use crate::reflect::acc::v1::FieldAccessorFunctions;
+use crate::reflect::acc::v1::FieldAccessorImpl;
+use crate::reflect::acc::v1::FieldAccessorTrait;
+use crate::Message;
+
+pub(crate) mod v1;
+
+pub(crate) enum Accessor {
+    V1(Box<dyn FieldAccessorTrait + 'static>),
+}
+
+/// Accessor object is constructed in generated code.
+/// Should not be used directly.
+pub struct FieldAccessor {
+    pub(crate) name: &'static str,
+    pub(crate) accessor: Accessor,
+}
+
+impl FieldAccessor {
+    pub(crate) fn new_v1<M: Message>(
+        name: &'static str,
+        fns: FieldAccessorFunctions<M>,
+    ) -> FieldAccessor {
+        FieldAccessor {
+            name,
+            accessor: Accessor::V1(Box::new(FieldAccessorImpl { fns })),
+        }
+    }
+}
diff --git a/src/reflect/accessor.rs b/src/reflect/acc/v1.rs
similarity index 60%
rename from src/reflect/accessor.rs
rename to src/reflect/acc/v1.rs
index 9f04838..5cf53d5 100644
--- a/src/reflect/accessor.rs
+++ b/src/reflect/acc/v1.rs
@@ -1,51 +1,52 @@
 #![doc(hidden)]
 
+//! Version 1 reflection accessors.
+
 use std::collections::HashMap;
 use std::fmt;
 use std::hash::Hash;
 
-use core::message_down_cast;
-use core::Message;
-use enums::ProtobufEnum;
-use reflect::EnumValueDescriptor;
-use types::*;
+use crate::enums::ProtobufEnum;
+use crate::message::message_down_cast;
+use crate::message::Message;
+use crate::reflect::EnumValueDescriptor;
+use crate::reflect::ProtobufValue;
+use crate::reflect::ReflectFieldRef;
+use crate::reflect::ReflectValueRef;
+use crate::types::*;
 
-use repeated::RepeatedField;
-use singular::SingularField;
-use singular::SingularPtrField;
-
-use super::map::ReflectMap;
-use super::optional::ReflectOptional;
-use super::repeated::ReflectRepeated;
-use super::repeated::ReflectRepeatedEnum;
-use super::repeated::ReflectRepeatedMessage;
-use super::value::ProtobufValue;
-use super::value::ReflectValueRef;
-use super::ReflectFieldRef;
+use crate::reflect::map::ReflectMap;
+use crate::reflect::optional::ReflectOptional;
+use crate::reflect::repeated::ReflectRepeated;
+use crate::reflect::repeated::ReflectRepeatedEnum;
+use crate::reflect::repeated::ReflectRepeatedMessage;
+use crate::reflect::rt::FieldAccessor;
+use crate::repeated::RepeatedField;
+use crate::singular::SingularField;
+use crate::singular::SingularPtrField;
 
 /// this trait should not be used directly, use `FieldDescriptor` instead
-pub trait FieldAccessor: Sync {
-    fn name_generic(&self) -> &'static str;
-    fn has_field_generic(&self, m: &Message) -> bool;
-    fn len_field_generic(&self, m: &Message) -> usize;
+pub trait FieldAccessorTrait: Sync + 'static {
+    fn has_field_generic(&self, m: &dyn Message) -> bool;
+    fn len_field_generic(&self, m: &dyn Message) -> usize;
     // TODO: should it return default value or panic on unset field?
-    fn get_message_generic<'a>(&self, m: &'a Message) -> &'a Message;
-    fn get_enum_generic(&self, m: &Message) -> &'static EnumValueDescriptor;
-    fn get_str_generic<'a>(&self, m: &'a Message) -> &'a str;
-    fn get_bytes_generic<'a>(&self, m: &'a Message) -> &'a [u8];
-    fn get_u32_generic(&self, m: &Message) -> u32;
-    fn get_u64_generic(&self, m: &Message) -> u64;
-    fn get_i32_generic(&self, m: &Message) -> i32;
-    fn get_i64_generic(&self, m: &Message) -> i64;
-    fn get_bool_generic(&self, m: &Message) -> bool;
-    fn get_f32_generic(&self, m: &Message) -> f32;
-    fn get_f64_generic(&self, m: &Message) -> f64;
+    fn get_message_generic<'a>(&self, m: &'a dyn Message) -> &'a dyn Message;
+    fn get_enum_generic(&self, m: &dyn Message) -> &'static EnumValueDescriptor;
+    fn get_str_generic<'a>(&self, m: &'a dyn Message) -> &'a str;
+    fn get_bytes_generic<'a>(&self, m: &'a dyn Message) -> &'a [u8];
+    fn get_u32_generic(&self, m: &dyn Message) -> u32;
+    fn get_u64_generic(&self, m: &dyn Message) -> u64;
+    fn get_i32_generic(&self, m: &dyn Message) -> i32;
+    fn get_i64_generic(&self, m: &dyn Message) -> i64;
+    fn get_bool_generic(&self, m: &dyn Message) -> bool;
+    fn get_f32_generic(&self, m: &dyn Message) -> f32;
+    fn get_f64_generic(&self, m: &dyn Message) -> f64;
 
-    fn get_reflect<'a>(&self, m: &'a Message) -> ReflectFieldRef<'a>;
+    fn get_reflect<'a>(&self, m: &'a dyn Message) -> ReflectFieldRef<'a>;
 }
 
-trait GetSingularMessage<M>: Sync {
-    fn get_message<'a>(&self, m: &'a M) -> &'a Message;
+pub(crate) trait GetSingularMessage<M>: Sync {
+    fn get_message<'a>(&self, m: &'a M) -> &'a dyn Message;
 }
 
 struct GetSingularMessageImpl<M, N> {
@@ -53,12 +54,12 @@
 }
 
 impl<M: Message, N: Message + 'static> GetSingularMessage<M> for GetSingularMessageImpl<M, N> {
-    fn get_message<'a>(&self, m: &'a M) -> &'a Message {
+    fn get_message<'a>(&self, m: &'a M) -> &'a dyn Message {
         (self.get)(m)
     }
 }
 
-trait GetSingularEnum<M>: Sync {
+pub(crate) trait GetSingularEnum<M>: Sync {
     fn get_enum(&self, m: &M) -> &'static EnumValueDescriptor;
 }
 
@@ -74,17 +75,17 @@
 
 trait GetRepeatedMessage<M>: Sync {
     fn len_field(&self, m: &M) -> usize;
-    fn get_message_item<'a>(&self, m: &'a M, index: usize) -> &'a Message;
-    fn reflect_repeated_message<'a>(&self, m: &'a M) -> Box<ReflectRepeatedMessage<'a> + 'a>;
+    fn get_message_item<'a>(&self, m: &'a M, index: usize) -> &'a dyn Message;
+    fn reflect_repeated_message<'a>(&self, m: &'a M) -> Box<dyn ReflectRepeatedMessage<'a> + 'a>;
 }
 
 trait GetRepeatedEnum<M: Message + 'static>: Sync {
     fn len_field(&self, m: &M) -> usize;
     fn get_enum_item(&self, m: &M, index: usize) -> &'static EnumValueDescriptor;
-    fn reflect_repeated_enum<'a>(&self, m: &'a M) -> Box<ReflectRepeatedEnum<'a> + 'a>;
+    fn reflect_repeated_enum<'a>(&self, m: &'a M) -> Box<dyn ReflectRepeatedEnum<'a> + 'a>;
 }
 
-trait GetSetCopyFns<M>: Sync {
+pub(crate) trait GetSetCopyFns<M>: Sync {
     fn get_field<'a>(&self, m: &'a M) -> ReflectValueRef<'a>;
 }
 
@@ -95,16 +96,16 @@
 
 impl<M, V: ProtobufValue + Copy> GetSetCopyFns<M> for GetSetCopyFnsImpl<M, V> {
     fn get_field<'a>(&self, m: &'a M) -> ReflectValueRef<'a> {
-        (&(self.get)(m) as &ProtobufValue).as_ref_copy()
+        (&(self.get)(m) as &dyn ProtobufValue).as_ref_copy()
     }
 }
 
-enum SingularGetSet<M> {
-    Copy(Box<GetSetCopyFns<M>>),
+pub(crate) enum SingularGetSet<M> {
+    Copy(Box<dyn GetSetCopyFns<M>>),
     String(for<'a> fn(&'a M) -> &'a str, fn(&mut M, String)),
     Bytes(for<'a> fn(&'a M) -> &'a [u8], fn(&mut M, Vec<u8>)),
-    Enum(Box<GetSingularEnum<M> + 'static>),
-    Message(Box<GetSingularMessage<M> + 'static>),
+    Enum(Box<dyn GetSingularEnum<M> + 'static>),
+    Message(Box<dyn GetSingularMessage<M> + 'static>),
 }
 
 impl<M: Message + 'static> SingularGetSet<M> {
@@ -119,12 +120,12 @@
     }
 }
 
-trait FieldAccessor2<M, R: ?Sized>: Sync
+pub(crate) trait FieldAccessor2<M, R: ?Sized>: Sync
 where
     M: Message + 'static,
 {
-    fn get_field<'a>(&self, &'a M) -> &'a R;
-    fn mut_field<'a>(&self, &'a mut M) -> &'a mut R;
+    fn get_field<'a>(&self, _: &'a M) -> &'a R;
+    fn mut_field<'a>(&self, _: &'a mut M) -> &'a mut R;
 }
 
 struct MessageGetMut<M, L>
@@ -135,20 +136,20 @@
     mut_field: for<'a> fn(&'a mut M) -> &'a mut L,
 }
 
-enum FieldAccessorFunctions<M> {
+pub(crate) enum FieldAccessorFunctions<M> {
     // up to 1.0.24 optional or required
     SingularHasGetSet {
         has: fn(&M) -> bool,
         get_set: SingularGetSet<M>,
     },
     // protobuf 3 simple field
-    Simple(Box<FieldAccessor2<M, ProtobufValue>>),
+    Simple(Box<dyn FieldAccessor2<M, dyn ProtobufValue>>),
     // optional, required or message
-    Optional(Box<FieldAccessor2<M, ReflectOptional>>),
+    Optional(Box<dyn FieldAccessor2<M, dyn ReflectOptional>>),
     // repeated
-    Repeated(Box<FieldAccessor2<M, ReflectRepeated>>),
+    Repeated(Box<dyn FieldAccessor2<M, dyn ReflectRepeated>>),
     // protobuf 3 map
-    Map(Box<FieldAccessor2<M, ReflectMap>>),
+    Map(Box<dyn FieldAccessor2<M, dyn ReflectMap>>),
 }
 
 impl<M> fmt::Debug for FieldAccessorFunctions<M> {
@@ -165,9 +166,8 @@
     }
 }
 
-struct FieldAccessorImpl<M> {
-    name: &'static str,
-    fns: FieldAccessorFunctions<M>,
+pub(crate) struct FieldAccessorImpl<M> {
+    pub(crate) fns: FieldAccessorFunctions<M>,
 }
 
 impl<M: Message> FieldAccessorImpl<M> {
@@ -194,12 +194,8 @@
     }
 }
 
-impl<M: Message + 'static> FieldAccessor for FieldAccessorImpl<M> {
-    fn name_generic(&self) -> &'static str {
-        self.name
-    }
-
-    fn has_field_generic(&self, m: &Message) -> bool {
+impl<M: Message + 'static> FieldAccessorTrait for FieldAccessorImpl<M> {
+    fn has_field_generic(&self, m: &dyn Message) -> bool {
         match self.fns {
             FieldAccessorFunctions::SingularHasGetSet { has, .. } => has(message_down_cast(m)),
             FieldAccessorFunctions::Optional(ref a) => {
@@ -214,7 +210,7 @@
         }
     }
 
-    fn len_field_generic(&self, m: &Message) -> usize {
+    fn len_field_generic(&self, m: &dyn Message) -> usize {
         match self.fns {
             FieldAccessorFunctions::Repeated(ref a) => a.get_field(message_down_cast(m)).len(),
             FieldAccessorFunctions::Map(ref a) => a.get_field(message_down_cast(m)).len(),
@@ -226,7 +222,7 @@
         }
     }
 
-    fn get_message_generic<'a>(&self, m: &'a Message) -> &'a Message {
+    fn get_message_generic<'a>(&self, m: &'a dyn Message) -> &'a dyn Message {
         match self.fns {
             FieldAccessorFunctions::SingularHasGetSet {
                 get_set: SingularGetSet::Message(ref get),
@@ -247,7 +243,7 @@
         }
     }
 
-    fn get_enum_generic(&self, m: &Message) -> &'static EnumValueDescriptor {
+    fn get_enum_generic(&self, m: &dyn Message) -> &'static EnumValueDescriptor {
         match self.fns {
             FieldAccessorFunctions::SingularHasGetSet {
                 get_set: SingularGetSet::Enum(ref get),
@@ -257,7 +253,7 @@
         }
     }
 
-    fn get_str_generic<'a>(&self, m: &'a Message) -> &'a str {
+    fn get_str_generic<'a>(&self, m: &'a dyn Message) -> &'a str {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::String(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -265,7 +261,7 @@
         }
     }
 
-    fn get_bytes_generic<'a>(&self, m: &'a Message) -> &'a [u8] {
+    fn get_bytes_generic<'a>(&self, m: &'a dyn Message) -> &'a [u8] {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::Bytes(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -273,7 +269,7 @@
         }
     }
 
-    fn get_u32_generic(&self, m: &Message) -> u32 {
+    fn get_u32_generic(&self, m: &dyn Message) -> u32 {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::U32(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -281,7 +277,7 @@
         }
     }
 
-    fn get_u64_generic(&self, m: &Message) -> u64 {
+    fn get_u64_generic(&self, m: &dyn Message) -> u64 {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::U64(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -289,7 +285,7 @@
         }
     }
 
-    fn get_i32_generic(&self, m: &Message) -> i32 {
+    fn get_i32_generic(&self, m: &dyn Message) -> i32 {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::I32(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -297,7 +293,7 @@
         }
     }
 
-    fn get_i64_generic(&self, m: &Message) -> i64 {
+    fn get_i64_generic(&self, m: &dyn Message) -> i64 {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::I64(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -305,23 +301,7 @@
         }
     }
 
-    fn get_f32_generic(&self, m: &Message) -> f32 {
-        match self.get_value_option(message_down_cast(m)) {
-            Some(ReflectValueRef::F32(v)) => v,
-            Some(_) => panic!("wrong type"),
-            None => 0.0, // TODO: check type
-        }
-    }
-
-    fn get_f64_generic(&self, m: &Message) -> f64 {
-        match self.get_value_option(message_down_cast(m)) {
-            Some(ReflectValueRef::F64(v)) => v,
-            Some(_) => panic!("wrong type"),
-            None => 0.0, // TODO: check type
-        }
-    }
-
-    fn get_bool_generic(&self, m: &Message) -> bool {
+    fn get_bool_generic(&self, m: &dyn Message) -> bool {
         match self.get_value_option(message_down_cast(m)) {
             Some(ReflectValueRef::Bool(v)) => v,
             Some(_) => panic!("wrong type"),
@@ -329,7 +309,23 @@
         }
     }
 
-    fn get_reflect<'a>(&self, m: &'a Message) -> ReflectFieldRef<'a> {
+    fn get_f32_generic(&self, m: &dyn Message) -> f32 {
+        match self.get_value_option(message_down_cast(m)) {
+            Some(ReflectValueRef::F32(v)) => v,
+            Some(_) => panic!("wrong type"),
+            None => 0.0, // TODO: check type
+        }
+    }
+
+    fn get_f64_generic(&self, m: &dyn Message) -> f64 {
+        match self.get_value_option(message_down_cast(m)) {
+            Some(ReflectValueRef::F64(v)) => v,
+            Some(_) => panic!("wrong type"),
+            None => 0.0, // TODO: check type
+        }
+    }
+
+    fn get_reflect<'a>(&self, m: &'a dyn Message) -> ReflectFieldRef<'a> {
         match self.fns {
             FieldAccessorFunctions::Repeated(ref accessor2) => {
                 ReflectFieldRef::Repeated(accessor2.get_field(message_down_cast(m)))
@@ -376,190 +372,190 @@
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> u32,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_i32_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> i32,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_u64_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> u64,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_i64_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> i64,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_f32_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> f32,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_f64_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> f64,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_bool_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> bool,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Copy(Box::new(GetSetCopyFnsImpl {
-                get: get,
+                get,
                 _set: set_panic,
             })),
         },
-    })
+    )
 }
 
 pub fn make_singular_enum_accessor<M: Message + 'static, E: ProtobufEnum + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: fn(&M) -> E,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
-            get_set: SingularGetSet::Enum(Box::new(GetSingularEnumImpl { get: get })),
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
+            get_set: SingularGetSet::Enum(Box::new(GetSingularEnumImpl { get })),
         },
-    })
+    )
 }
 
 pub fn make_singular_string_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: for<'a> fn(&'a M) -> &'a str,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::String(get, set_panic),
         },
-    })
+    )
 }
 
 pub fn make_singular_bytes_accessor<M: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: for<'a> fn(&'a M) -> &'a [u8],
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
             get_set: SingularGetSet::Bytes(get, set_panic),
         },
-    })
+    )
 }
 
 pub fn make_singular_message_accessor<M: Message + 'static, F: Message + 'static>(
     name: &'static str,
     has: fn(&M) -> bool,
     get: for<'a> fn(&'a M) -> &'a F,
-) -> Box<FieldAccessor + 'static> {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::SingularHasGetSet {
-            has: has,
-            get_set: SingularGetSet::Message(Box::new(GetSingularMessageImpl { get: get })),
+) -> FieldAccessor {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::SingularHasGetSet {
+            has,
+            get_set: SingularGetSet::Message(Box::new(GetSingularMessageImpl { get })),
         },
-    })
+    )
 }
 
 // repeated
 
-impl<M, V> FieldAccessor2<M, ReflectRepeated> for MessageGetMut<M, Vec<V>>
+impl<M, V> FieldAccessor2<M, dyn ReflectRepeated> for MessageGetMut<M, Vec<V>>
 where
     M: Message + 'static,
     V: ProtobufValue + 'static,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ReflectRepeated {
-        (self.get_field)(m) as &ReflectRepeated
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectRepeated {
+        (self.get_field)(m) as &dyn ReflectRepeated
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ReflectRepeated {
-        (self.mut_field)(m) as &mut ReflectRepeated
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectRepeated {
+        (self.mut_field)(m) as &mut dyn ReflectRepeated
     }
 }
 
@@ -567,31 +563,31 @@
     name: &'static str,
     get_vec: for<'a> fn(&'a M) -> &'a Vec<V::Value>,
     mut_vec: for<'a> fn(&'a mut M) -> &'a mut Vec<V::Value>,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     V: ProtobufType + 'static,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Repeated(Box::new(MessageGetMut::<M, Vec<V::Value>> {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Repeated(Box::new(MessageGetMut::<M, Vec<V::Value>> {
             get_field: get_vec,
             mut_field: mut_vec,
         })),
-    })
+    )
 }
 
-impl<M, V> FieldAccessor2<M, ReflectRepeated> for MessageGetMut<M, RepeatedField<V>>
+impl<M, V> FieldAccessor2<M, dyn ReflectRepeated> for MessageGetMut<M, RepeatedField<V>>
 where
     M: Message + 'static,
     V: ProtobufValue + 'static,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ReflectRepeated {
-        (self.get_field)(m) as &ReflectRepeated
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectRepeated {
+        (self.get_field)(m) as &dyn ReflectRepeated
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ReflectRepeated {
-        (self.mut_field)(m) as &mut ReflectRepeated
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectRepeated {
+        (self.mut_field)(m) as &mut dyn ReflectRepeated
     }
 }
 
@@ -599,34 +595,31 @@
     name: &'static str,
     get_vec: for<'a> fn(&'a M) -> &'a RepeatedField<V::Value>,
     mut_vec: for<'a> fn(&'a mut M) -> &'a mut RepeatedField<V::Value>,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     V: ProtobufType + 'static,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Repeated(Box::new(MessageGetMut::<
-            M,
-            RepeatedField<V::Value>,
-        > {
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Repeated(Box::new(MessageGetMut::<M, RepeatedField<V::Value>> {
             get_field: get_vec,
             mut_field: mut_vec,
         })),
-    })
+    )
 }
 
-impl<M, V> FieldAccessor2<M, ReflectOptional> for MessageGetMut<M, Option<V>>
+impl<M, V> FieldAccessor2<M, dyn ReflectOptional> for MessageGetMut<M, Option<V>>
 where
     M: Message + 'static,
     V: ProtobufValue + Clone + 'static,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ReflectOptional {
-        (self.get_field)(m) as &ReflectOptional
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectOptional {
+        (self.get_field)(m) as &dyn ReflectOptional
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ReflectOptional {
-        (self.mut_field)(m) as &mut ReflectOptional
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectOptional {
+        (self.mut_field)(m) as &mut dyn ReflectOptional
     }
 }
 
@@ -634,31 +627,31 @@
     name: &'static str,
     get_field: for<'a> fn(&'a M) -> &'a Option<V::Value>,
     mut_field: for<'a> fn(&'a mut M) -> &'a mut Option<V::Value>,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     V: ProtobufType + 'static,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Optional(Box::new(MessageGetMut::<M, Option<V::Value>> {
-            get_field: get_field,
-            mut_field: mut_field,
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Optional(Box::new(MessageGetMut::<M, Option<V::Value>> {
+            get_field,
+            mut_field,
         })),
-    })
+    )
 }
 
-impl<M, V> FieldAccessor2<M, ReflectOptional> for MessageGetMut<M, SingularField<V>>
+impl<M, V> FieldAccessor2<M, dyn ReflectOptional> for MessageGetMut<M, SingularField<V>>
 where
     M: Message + 'static,
     V: ProtobufValue + Clone + 'static,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ReflectOptional {
-        (self.get_field)(m) as &ReflectOptional
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectOptional {
+        (self.get_field)(m) as &dyn ReflectOptional
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ReflectOptional {
-        (self.mut_field)(m) as &mut ReflectOptional
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectOptional {
+        (self.mut_field)(m) as &mut dyn ReflectOptional
     }
 }
 
@@ -666,34 +659,31 @@
     name: &'static str,
     get_field: for<'a> fn(&'a M) -> &'a SingularField<V::Value>,
     mut_field: for<'a> fn(&'a mut M) -> &'a mut SingularField<V::Value>,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     V: ProtobufType + 'static,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Optional(Box::new(MessageGetMut::<
-            M,
-            SingularField<V::Value>,
-        > {
-            get_field: get_field,
-            mut_field: mut_field,
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Optional(Box::new(MessageGetMut::<M, SingularField<V::Value>> {
+            get_field,
+            mut_field,
         })),
-    })
+    )
 }
 
-impl<M, V> FieldAccessor2<M, ReflectOptional> for MessageGetMut<M, SingularPtrField<V>>
+impl<M, V> FieldAccessor2<M, dyn ReflectOptional> for MessageGetMut<M, SingularPtrField<V>>
 where
     M: Message + 'static,
     V: ProtobufValue + Clone + 'static,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ReflectOptional {
-        (self.get_field)(m) as &ReflectOptional
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectOptional {
+        (self.get_field)(m) as &dyn ReflectOptional
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ReflectOptional {
-        (self.mut_field)(m) as &mut ReflectOptional
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectOptional {
+        (self.mut_field)(m) as &mut dyn ReflectOptional
     }
 }
 
@@ -701,34 +691,33 @@
     name: &'static str,
     get_field: for<'a> fn(&'a M) -> &'a SingularPtrField<V::Value>,
     mut_field: for<'a> fn(&'a mut M) -> &'a mut SingularPtrField<V::Value>,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     V: ProtobufType + 'static,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Optional(Box::new(MessageGetMut::<
-            M,
-            SingularPtrField<V::Value>,
-        > {
-            get_field: get_field,
-            mut_field: mut_field,
-        })),
-    })
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Optional(Box::new(
+            MessageGetMut::<M, SingularPtrField<V::Value>> {
+                get_field,
+                mut_field,
+            },
+        )),
+    )
 }
 
-impl<M, V> FieldAccessor2<M, ProtobufValue> for MessageGetMut<M, V>
+impl<M, V> FieldAccessor2<M, dyn ProtobufValue> for MessageGetMut<M, V>
 where
     M: Message + 'static,
     V: ProtobufValue + Clone + 'static,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ProtobufValue {
-        (self.get_field)(m) as &ProtobufValue
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ProtobufValue {
+        (self.get_field)(m) as &dyn ProtobufValue
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ProtobufValue {
-        (self.mut_field)(m) as &mut ProtobufValue
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ProtobufValue {
+        (self.mut_field)(m) as &mut dyn ProtobufValue
     }
 }
 
@@ -736,33 +725,33 @@
     name: &'static str,
     get_field: for<'a> fn(&'a M) -> &'a V::Value,
     mut_field: for<'a> fn(&'a mut M) -> &'a mut V::Value,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     V: ProtobufType + 'static,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Simple(Box::new(MessageGetMut::<M, V::Value> {
-            get_field: get_field,
-            mut_field: mut_field,
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Simple(Box::new(MessageGetMut::<M, V::Value> {
+            get_field,
+            mut_field,
         })),
-    })
+    )
 }
 
-impl<M, K, V> FieldAccessor2<M, ReflectMap> for MessageGetMut<M, HashMap<K, V>>
+impl<M, K, V> FieldAccessor2<M, dyn ReflectMap> for MessageGetMut<M, HashMap<K, V>>
 where
     M: Message + 'static,
     K: ProtobufValue + 'static,
     V: ProtobufValue + 'static,
     K: Hash + Eq,
 {
-    fn get_field<'a>(&self, m: &'a M) -> &'a ReflectMap {
-        (self.get_field)(m) as &ReflectMap
+    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectMap {
+        (self.get_field)(m) as &dyn ReflectMap
     }
 
-    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut ReflectMap {
-        (self.mut_field)(m) as &mut ReflectMap
+    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectMap {
+        (self.mut_field)(m) as &mut dyn ReflectMap
     }
 }
 
@@ -770,20 +759,18 @@
     name: &'static str,
     get_field: for<'a> fn(&'a M) -> &'a HashMap<K::Value, V::Value>,
     mut_field: for<'a> fn(&'a mut M) -> &'a mut HashMap<K::Value, V::Value>,
-) -> Box<FieldAccessor + 'static>
+) -> FieldAccessor
 where
     M: Message + 'static,
     K: ProtobufType + 'static,
     V: ProtobufType + 'static,
     <K as ProtobufType>::Value: Hash + Eq,
 {
-    Box::new(FieldAccessorImpl {
-        name: name,
-        fns: FieldAccessorFunctions::Map(Box::new(
-            MessageGetMut::<M, HashMap<K::Value, V::Value>> {
-                get_field: get_field,
-                mut_field: mut_field,
-            },
-        )),
-    })
+    FieldAccessor::new_v1(
+        name,
+        FieldAccessorFunctions::Map(Box::new(MessageGetMut::<M, HashMap<K::Value, V::Value>> {
+            get_field,
+            mut_field,
+        })),
+    )
 }
diff --git a/src/reflect/accessor/mod.rs b/src/reflect/accessor/mod.rs
new file mode 100644
index 0000000..9fa97de
--- /dev/null
+++ b/src/reflect/accessor/mod.rs
@@ -0,0 +1,21 @@
+#![doc(hidden)]
+
+pub use crate::reflect::acc::v1::make_map_accessor;
+pub use crate::reflect::acc::v1::make_option_accessor;
+pub use crate::reflect::acc::v1::make_repeated_field_accessor;
+pub use crate::reflect::acc::v1::make_simple_field_accessor;
+pub use crate::reflect::acc::v1::make_singular_bool_accessor;
+pub use crate::reflect::acc::v1::make_singular_bytes_accessor;
+pub use crate::reflect::acc::v1::make_singular_enum_accessor;
+pub use crate::reflect::acc::v1::make_singular_f32_accessor;
+pub use crate::reflect::acc::v1::make_singular_f64_accessor;
+pub use crate::reflect::acc::v1::make_singular_field_accessor;
+pub use crate::reflect::acc::v1::make_singular_i32_accessor;
+pub use crate::reflect::acc::v1::make_singular_i64_accessor;
+pub use crate::reflect::acc::v1::make_singular_message_accessor;
+pub use crate::reflect::acc::v1::make_singular_ptr_field_accessor;
+pub use crate::reflect::acc::v1::make_singular_string_accessor;
+pub use crate::reflect::acc::v1::make_singular_u32_accessor;
+pub use crate::reflect::acc::v1::make_singular_u64_accessor;
+pub use crate::reflect::acc::v1::make_vec_accessor;
+pub use crate::reflect::acc::v1::FieldAccessorTrait;
diff --git a/src/reflect/enums.rs b/src/reflect/enums.rs
index e4ba4f6..f1ad901 100644
--- a/src/reflect/enums.rs
+++ b/src/reflect/enums.rs
@@ -1,11 +1,11 @@
-use descriptor::EnumDescriptorProto;
-use descriptor::EnumValueDescriptorProto;
-use descriptor::FileDescriptorProto;
-use descriptorx::find_enum_by_rust_name;
-use reflect::find_message_or_enum::find_message_or_enum;
-use reflect::find_message_or_enum::MessageOrEnum;
+use crate::descriptor::EnumDescriptorProto;
+use crate::descriptor::EnumValueDescriptorProto;
+use crate::descriptor::FileDescriptorProto;
+use crate::descriptorx::find_enum_by_rust_name;
+use crate::reflect::find_message_or_enum::find_message_or_enum;
+use crate::reflect::find_message_or_enum::MessageOrEnum;
+use crate::ProtobufEnum;
 use std::collections::HashMap;
-use ProtobufEnum;
 
 /// Description for enum variant.
 ///
diff --git a/src/reflect/field.rs b/src/reflect/field.rs
index ecac510..09ee222 100644
--- a/src/reflect/field.rs
+++ b/src/reflect/field.rs
@@ -1,9 +1,13 @@
-use descriptor::{FieldDescriptorProto, FieldDescriptorProto_Label};
-use reflect::accessor::FieldAccessor;
-use reflect::map::ReflectMap;
-use reflect::repeated::ReflectRepeated;
-use reflect::{EnumValueDescriptor, ReflectValueRef};
-use Message;
+use crate::descriptor::FieldDescriptorProto;
+use crate::descriptor::FieldDescriptorProto_Label;
+use crate::json::json_name;
+use crate::message::Message;
+use crate::reflect::acc::Accessor;
+use crate::reflect::acc::FieldAccessor;
+use crate::reflect::map::ReflectMap;
+use crate::reflect::repeated::ReflectRepeated;
+use crate::reflect::EnumValueDescriptor;
+use crate::reflect::ReflectValueRef;
 
 /// Reference to a value stored in a field, optional, repeated or map.
 // TODO: implement Eq
@@ -11,9 +15,9 @@
     /// Singular field, optional or required in proto3 and just plain field in proto3
     Optional(Option<ReflectValueRef<'a>>),
     /// Repeated field
-    Repeated(&'a ReflectRepeated),
+    Repeated(&'a dyn ReflectRepeated),
     /// Map field
-    Map(&'a ReflectMap),
+    Map(&'a dyn ReflectMap),
 }
 
 /// Field descriptor.
@@ -21,16 +25,27 @@
 /// Can be used for runtime reflection.
 pub struct FieldDescriptor {
     proto: &'static FieldDescriptorProto,
-    accessor: Box<FieldAccessor + 'static>,
+    accessor: FieldAccessor,
+    json_name: String,
 }
 
 impl FieldDescriptor {
     pub(crate) fn new(
-        accessor: Box<FieldAccessor + 'static>,
+        accessor: FieldAccessor,
         proto: &'static FieldDescriptorProto,
     ) -> FieldDescriptor {
-        assert_eq!(proto.get_name(), accessor.name_generic());
-        FieldDescriptor { proto, accessor }
+        assert_eq!(proto.get_name(), accessor.name);
+        let json_name = if !proto.get_json_name().is_empty() {
+            proto.get_json_name().to_string()
+        } else {
+            json_name(proto.get_name())
+        };
+        FieldDescriptor {
+            proto,
+            accessor,
+            // probably could be lazy-init
+            json_name,
+        }
     }
 
     /// Get `.proto` description of field
@@ -43,6 +58,17 @@
         self.proto.get_name()
     }
 
+    /// JSON field name.
+    ///
+    /// Can be different from `.proto` field name.
+    ///
+    /// See [JSON mapping][json] for details.
+    ///
+    /// [json]: https://developers.google.com/protocol-buffers/docs/proto3#json
+    pub fn json_name(&self) -> &str {
+        &self.json_name
+    }
+
     /// If this field repeated?
     pub fn is_repeated(&self) -> bool {
         self.proto.get_label() == FieldDescriptorProto_Label::LABEL_REPEATED
@@ -56,19 +82,23 @@
     /// # Panics
     ///
     /// If this field belongs to a different message type.
-    pub fn has_field(&self, m: &Message) -> bool {
-        self.accessor.has_field_generic(m)
+    pub fn has_field(&self, m: &dyn Message) -> bool {
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.has_field_generic(m),
+        }
     }
 
     /// Return length of repeated field.
     ///
-    /// For singualar field return `1` if field is set and `0` otherwise.
+    /// For singular field return `1` if field is set and `0` otherwise.
     ///
     /// # Panics
     ///
     /// If this field belongs to a different message type.
     pub fn len_field(&self, m: &dyn Message) -> usize {
-        self.accessor.len_field_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.len_field_generic(m),
+        }
     }
 
     /// Get message field or default instance if field is unset.
@@ -77,7 +107,9 @@
     /// If this field belongs to a different message type or
     /// field type is not message.
     pub fn get_message<'a>(&self, m: &'a dyn Message) -> &'a dyn Message {
-        self.accessor.get_message_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_message_generic(m),
+        }
     }
 
     /// Get `enum` field.
@@ -87,7 +119,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `enum`.
     pub fn get_enum(&self, m: &dyn Message) -> &'static EnumValueDescriptor {
-        self.accessor.get_enum_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_enum_generic(m),
+        }
     }
 
     /// Get `string` field.
@@ -97,7 +131,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `string`.
     pub fn get_str<'a>(&self, m: &'a dyn Message) -> &'a str {
-        self.accessor.get_str_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_str_generic(m),
+        }
     }
 
     /// Get `bytes` field.
@@ -107,7 +143,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `bytes`.
     pub fn get_bytes<'a>(&self, m: &'a dyn Message) -> &'a [u8] {
-        self.accessor.get_bytes_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_bytes_generic(m),
+        }
     }
 
     /// Get `u32` field.
@@ -117,7 +155,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `u32`.
     pub fn get_u32(&self, m: &dyn Message) -> u32 {
-        self.accessor.get_u32_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_u32_generic(m),
+        }
     }
 
     /// Get `u64` field.
@@ -127,7 +167,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `u64`.
     pub fn get_u64(&self, m: &dyn Message) -> u64 {
-        self.accessor.get_u64_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_u64_generic(m),
+        }
     }
 
     /// Get `i32` field.
@@ -137,7 +179,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `i32`.
     pub fn get_i32(&self, m: &dyn Message) -> i32 {
-        self.accessor.get_i32_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_i32_generic(m),
+        }
     }
 
     /// Get `i64` field.
@@ -147,7 +191,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `i64`.
     pub fn get_i64(&self, m: &dyn Message) -> i64 {
-        self.accessor.get_i64_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_i64_generic(m),
+        }
     }
 
     /// Get `bool` field.
@@ -157,7 +203,9 @@
     /// If this field belongs to a different message type or
     /// field type is not singular `bool`.
     pub fn get_bool(&self, m: &dyn Message) -> bool {
-        self.accessor.get_bool_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_bool_generic(m),
+        }
     }
 
     /// Get `float` field.
@@ -167,7 +215,9 @@
     /// If this field belongs to a different message type or
     /// field type is not singular `float`.
     pub fn get_f32(&self, m: &dyn Message) -> f32 {
-        self.accessor.get_f32_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_f32_generic(m),
+        }
     }
 
     /// Get `double` field.
@@ -177,7 +227,9 @@
     /// If this field belongs to a different message type
     /// or field type is not singular `double`.
     pub fn get_f64(&self, m: &dyn Message) -> f64 {
-        self.accessor.get_f64_generic(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_f64_generic(m),
+        }
     }
 
     /// Get field of any type.
@@ -186,6 +238,8 @@
     ///
     /// If this field belongs to a different message type.
     pub fn get_reflect<'a>(&self, m: &'a dyn Message) -> ReflectFieldRef<'a> {
-        self.accessor.get_reflect(m)
+        match &self.accessor.accessor {
+            Accessor::V1(a) => a.get_reflect(m),
+        }
     }
 }
diff --git a/src/reflect/message.rs b/src/reflect/message.rs
index c35a854..4730306 100644
--- a/src/reflect/message.rs
+++ b/src/reflect/message.rs
@@ -1,12 +1,12 @@
-use descriptor::{DescriptorProto, FileDescriptorProto};
-use descriptorx::find_message_by_rust_name;
-use reflect::accessor::FieldAccessor;
-use reflect::find_message_or_enum::find_message_or_enum;
-use reflect::find_message_or_enum::MessageOrEnum;
-use reflect::FieldDescriptor;
+use crate::descriptor::{DescriptorProto, FileDescriptorProto};
+use crate::descriptorx::find_message_by_rust_name;
+use crate::reflect::acc::FieldAccessor;
+use crate::reflect::find_message_or_enum::find_message_or_enum;
+use crate::reflect::find_message_or_enum::MessageOrEnum;
+use crate::reflect::FieldDescriptor;
+use crate::Message;
 use std::collections::HashMap;
 use std::marker;
-use Message;
 
 trait MessageFactory: Send + Sync + 'static {
     fn new_instance(&self) -> Box<dyn Message>;
@@ -32,6 +32,7 @@
     fields: Vec<FieldDescriptor>,
 
     index_by_name: HashMap<String, usize>,
+    index_by_name_or_json_name: HashMap<String, usize>,
     index_by_number: HashMap<u32, usize>,
 }
 
@@ -65,7 +66,7 @@
     // to reduce code bloat from multiple instantiations.
     fn new_non_generic_by_rust_name(
         rust_name: &'static str,
-        fields: Vec<Box<FieldAccessor + 'static>>,
+        fields: Vec<FieldAccessor>,
         file: &'static FileDescriptorProto,
         factory: &'static dyn MessageFactory,
     ) -> MessageDescriptor {
@@ -77,11 +78,8 @@
         }
 
         let mut index_by_name = HashMap::new();
+        let mut index_by_name_or_json_name = HashMap::new();
         let mut index_by_number = HashMap::new();
-        for (i, f) in proto.message.get_field().iter().enumerate() {
-            index_by_number.insert(f.get_number() as u32, i);
-            index_by_name.insert(f.get_name().to_string(), i);
-        }
 
         let mut full_name = file.get_package().to_string();
         if full_name.len() > 0 {
@@ -89,18 +87,37 @@
         }
         full_name.push_str(proto.message.get_name());
 
+        let fields: Vec<_> = fields
+            .into_iter()
+            .map(|f| {
+                let proto = *field_proto_by_name.get(&f.name).unwrap();
+                FieldDescriptor::new(f, proto)
+            })
+            .collect();
+        for (i, f) in fields.iter().enumerate() {
+            assert!(index_by_number
+                .insert(f.proto().get_number() as u32, i)
+                .is_none());
+            assert!(index_by_name
+                .insert(f.proto().get_name().to_owned(), i)
+                .is_none());
+            assert!(index_by_name_or_json_name
+                .insert(f.proto().get_name().to_owned(), i)
+                .is_none());
+
+            let json_name = f.json_name().to_owned();
+
+            if json_name != f.proto().get_name() {
+                assert!(index_by_name_or_json_name.insert(json_name, i).is_none());
+            }
+        }
         MessageDescriptor {
-            full_name: full_name,
+            full_name,
             proto: proto.message,
             factory,
-            fields: fields
-                .into_iter()
-                .map(|f| {
-                    let proto = *field_proto_by_name.get(&f.name_generic()).unwrap();
-                    FieldDescriptor::new(f, proto)
-                })
-                .collect(),
+            fields,
             index_by_name,
+            index_by_name_or_json_name,
             index_by_number,
         }
     }
@@ -109,7 +126,7 @@
     // to reduce code bloat from multiple instantiations.
     fn new_non_generic_by_pb_name(
         protobuf_name_to_package: &'static str,
-        fields: Vec<Box<FieldAccessor + 'static>>,
+        fields: Vec<FieldAccessor>,
         file_descriptor_proto: &'static FileDescriptorProto,
         factory: &'static dyn MessageFactory,
     ) -> MessageDescriptor {
@@ -125,28 +142,46 @@
         }
 
         let mut index_by_name = HashMap::new();
+        let mut index_by_name_or_json_name = HashMap::new();
         let mut index_by_number = HashMap::new();
-        for (i, f) in proto.get_field().iter().enumerate() {
-            index_by_number.insert(f.get_number() as u32, i);
-            index_by_name.insert(f.get_name().to_string(), i);
-        }
 
+        let full_name = MessageDescriptor::compute_full_name(
+            file_descriptor_proto.get_package(),
+            &path_to_package,
+            &proto,
+        );
+        let fields: Vec<_> = fields
+            .into_iter()
+            .map(|f| {
+                let proto = *field_proto_by_name.get(&f.name).unwrap();
+                FieldDescriptor::new(f, proto)
+            })
+            .collect();
+
+        for (i, f) in fields.iter().enumerate() {
+            assert!(index_by_number
+                .insert(f.proto().get_number() as u32, i)
+                .is_none());
+            assert!(index_by_name
+                .insert(f.proto().get_name().to_owned(), i)
+                .is_none());
+            assert!(index_by_name_or_json_name
+                .insert(f.proto().get_name().to_owned(), i)
+                .is_none());
+
+            let json_name = f.json_name().to_owned();
+
+            if json_name != f.proto().get_name() {
+                assert!(index_by_name_or_json_name.insert(json_name, i).is_none());
+            }
+        }
         MessageDescriptor {
-            full_name: MessageDescriptor::compute_full_name(
-                file_descriptor_proto.get_package(),
-                &path_to_package,
-                &proto,
-            ),
+            full_name,
             proto,
             factory,
-            fields: fields
-                .into_iter()
-                .map(|f| {
-                    let proto = *field_proto_by_name.get(&f.name_generic()).unwrap();
-                    FieldDescriptor::new(f, proto)
-                })
-                .collect(),
+            fields,
             index_by_name,
+            index_by_name_or_json_name,
             index_by_number,
         }
     }
@@ -162,7 +197,7 @@
     )]
     pub fn new<M: 'static + Message + Default + Clone + PartialEq>(
         rust_name: &'static str,
-        fields: Vec<Box<FieldAccessor + 'static>>,
+        fields: Vec<FieldAccessor>,
         file: &'static FileDescriptorProto,
     ) -> MessageDescriptor {
         let factory = &MessageFactoryImpl(marker::PhantomData::<M>);
@@ -176,7 +211,7 @@
     #[doc(hidden)]
     pub fn new_pb_name<M: 'static + Message + Default + Clone + PartialEq>(
         protobuf_name_to_package: &'static str,
-        fields: Vec<Box<FieldAccessor + 'static>>,
+        fields: Vec<FieldAccessor>,
         file_descriptor_proto: &'static FileDescriptorProto,
     ) -> MessageDescriptor {
         let factory = &MessageFactoryImpl(marker::PhantomData::<M>);
@@ -193,7 +228,7 @@
         self.factory.new_instance()
     }
 
-    /// Protobuf message name
+    /// Message name as given in `.proto` file
     pub fn name(&self) -> &'static str {
         self.proto.get_name()
     }
@@ -208,7 +243,28 @@
         &self.fields
     }
 
+    /// Find message field by protobuf field name
+    ///
+    /// Note: protobuf field name might be different for Rust field name.
+    pub fn get_field_by_name<'a>(&'a self, name: &str) -> Option<&'a FieldDescriptor> {
+        let &index = self.index_by_name.get(name)?;
+        Some(&self.fields[index])
+    }
+
+    /// Find message field by field name or field JSON name
+    pub fn get_field_by_name_or_json_name<'a>(&'a self, name: &str) -> Option<&'a FieldDescriptor> {
+        let &index = self.index_by_name_or_json_name.get(name)?;
+        Some(&self.fields[index])
+    }
+
+    /// Find message field by field name
+    pub fn get_field_by_number(&self, number: u32) -> Option<&FieldDescriptor> {
+        let &index = self.index_by_number.get(&number)?;
+        Some(&self.fields[index])
+    }
+
     /// Find field by name
+    // TODO: deprecate
     pub fn field_by_name<'a>(&'a self, name: &str) -> &'a FieldDescriptor {
         // TODO: clone is weird
         let &index = self.index_by_name.get(&name.to_string()).unwrap();
@@ -216,6 +272,7 @@
     }
 
     /// Find field by number
+    // TODO: deprecate
     pub fn field_by_number<'a>(&'a self, number: u32) -> &'a FieldDescriptor {
         let &index = self.index_by_number.get(&number).unwrap();
         &self.fields[index]
diff --git a/src/reflect/mod.rs b/src/reflect/mod.rs
index ede3743..392f629 100644
--- a/src/reflect/mod.rs
+++ b/src/reflect/mod.rs
@@ -1,7 +1,8 @@
 //! Reflection implementation for protobuf types.
 
-use core::Message;
+use crate::message::Message;
 
+mod acc;
 pub mod accessor;
 mod enums;
 mod field;
@@ -18,6 +19,8 @@
 #[deprecated(since = "2.11", note = "Use ReflectValueRef instead")]
 pub use self::value::ReflectValueRef as ProtobufValueRef;
 
+pub mod rt;
+
 pub use self::enums::EnumDescriptor;
 pub use self::enums::EnumValueDescriptor;
 
diff --git a/src/reflect/optional.rs b/src/reflect/optional.rs
index 4d33752..ba6cbaf 100644
--- a/src/reflect/optional.rs
+++ b/src/reflect/optional.rs
@@ -2,7 +2,7 @@
 
 use super::value::ProtobufValue;
 
-use singular::*;
+use crate::singular::*;
 
 pub trait ReflectOptional: 'static {
     fn to_option(&self) -> Option<&ProtobufValue>;
diff --git a/src/reflect/repeated.rs b/src/reflect/repeated.rs
index 7ffc979..43e265d 100644
--- a/src/reflect/repeated.rs
+++ b/src/reflect/repeated.rs
@@ -3,7 +3,7 @@
 use super::value::ProtobufValue;
 use super::value::ReflectValueRef;
 
-use repeated::RepeatedField;
+use crate::repeated::RepeatedField;
 
 pub trait ReflectRepeated: 'static {
     fn reflect_iter(&self) -> ReflectRepeatedIter;
diff --git a/src/reflect/rt/mod.rs b/src/reflect/rt/mod.rs
new file mode 100644
index 0000000..d715d92
--- /dev/null
+++ b/src/reflect/rt/mod.rs
@@ -0,0 +1,5 @@
+//! This module contains functions references for reflection in generated code.
+
+#![doc(hidden)]
+
+pub use crate::reflect::acc::FieldAccessor;
diff --git a/src/reflect/value.rs b/src/reflect/value.rs
index 22f76af..2671805 100644
--- a/src/reflect/value.rs
+++ b/src/reflect/value.rs
@@ -1,9 +1,9 @@
 use std::any::Any;
 
 #[cfg(feature = "bytes")]
-use bytes::Bytes;
+use crate::chars::Chars;
 #[cfg(feature = "bytes")]
-use chars::Chars;
+use bytes::Bytes;
 
 use super::*;