Import protobuf-codegen-2.14.0

* Add OWNERS, Android.bp, and README.android.
* Hard code version number in src/lib.rs for now.
  It could be in a smarter update_package.sh to get the
  new version number from Cargo.tom. But until then,
  the difference in lib.rs will be caught and fixed manually.
* Rename protoc_gen_rust to protoc-gen-rust for aprotoc plugin.

Bug: 143953733
Test: make
Change-Id: I9b3c3b9f2e7ad0eb203c26534f2b6ba5fac46eef
diff --git a/src/enums.rs b/src/enums.rs
new file mode 100644
index 0000000..2c60f0c
--- /dev/null
+++ b/src/enums.rs
@@ -0,0 +1,324 @@
+use std::collections::HashSet;
+
+use protobuf::descriptor::*;
+
+use super::code_writer::*;
+use super::customize::Customize;
+use file_descriptor::file_descriptor_proto_expr;
+use protobuf_name::ProtobufAbsolutePath;
+use rust_types_values::type_name_to_rust_relative;
+use scope::EnumWithScope;
+use scope::RootScope;
+use scope::WithScope;
+use serde;
+
+#[derive(Clone)]
+pub struct EnumValueGen {
+    proto: EnumValueDescriptorProto,
+    enum_rust_name: String,
+    variant_rust_name: String,
+}
+
+impl EnumValueGen {
+    fn parse(
+        proto: &EnumValueDescriptorProto,
+        enum_rust_name: &str,
+        variant_rust_name: &str,
+    ) -> EnumValueGen {
+        EnumValueGen {
+            proto: proto.clone(),
+            enum_rust_name: enum_rust_name.to_string(),
+            variant_rust_name: variant_rust_name.to_string(),
+        }
+    }
+
+    // enum value
+    fn number(&self) -> i32 {
+        self.proto.get_number()
+    }
+
+    // name of enum variant in generated rust code
+    fn rust_name_inner(&self) -> String {
+        self.variant_rust_name.clone()
+    }
+
+    pub fn rust_name_outer(&self) -> String {
+        let mut r = String::new();
+        r.push_str(&self.enum_rust_name);
+        r.push_str("::");
+        r.push_str(&self.rust_name_inner());
+        r
+    }
+}
+
+pub(crate) struct EnumGen<'a> {
+    enum_with_scope: &'a EnumWithScope<'a>,
+    type_name: String,
+    lite_runtime: bool,
+    customize: Customize,
+}
+
+impl<'a> EnumGen<'a> {
+    pub fn new(
+        enum_with_scope: &'a EnumWithScope<'a>,
+        current_file: &FileDescriptorProto,
+        customize: &Customize,
+        root_scope: &RootScope,
+    ) -> EnumGen<'a> {
+        let rust_name = if enum_with_scope.get_scope().get_file_descriptor().get_name()
+            == current_file.get_name()
+        {
+            // field type is a message or enum declared in the same file
+            enum_with_scope.rust_name().to_string()
+        } else {
+            type_name_to_rust_relative(
+                &ProtobufAbsolutePath::from(enum_with_scope.name_absolute()),
+                current_file,
+                false,
+                root_scope,
+            )
+            .to_string()
+        };
+        let lite_runtime = customize.lite_runtime.unwrap_or_else(|| {
+            enum_with_scope
+                .get_scope()
+                .get_file_descriptor()
+                .get_options()
+                .get_optimize_for()
+                == FileOptions_OptimizeMode::LITE_RUNTIME
+        });
+
+        EnumGen {
+            enum_with_scope,
+            type_name: rust_name,
+            lite_runtime,
+            customize: customize.clone(),
+        }
+    }
+
+    fn allow_alias(&self) -> bool {
+        self.enum_with_scope.en.get_options().get_allow_alias()
+    }
+
+    fn values_all(&self) -> Vec<EnumValueGen> {
+        let mut r = Vec::new();
+        for p in self.enum_with_scope.values() {
+            r.push(EnumValueGen::parse(
+                &p.proto,
+                &self.type_name,
+                p.rust_name().get(),
+            ));
+        }
+        r
+    }
+
+    pub fn values_unique(&self) -> Vec<EnumValueGen> {
+        let mut used = HashSet::new();
+        let mut r = Vec::new();
+        for p in self.enum_with_scope.values() {
+            // skipping non-unique enums
+            // TODO: should support it
+            if !used.insert(p.proto.get_number()) {
+                continue;
+            }
+            r.push(EnumValueGen::parse(
+                p.proto,
+                &self.type_name,
+                p.rust_name().get(),
+            ));
+        }
+        r
+    }
+
+    // find enum value by name
+    pub fn value_by_name(&'a self, name: &str) -> EnumValueGen {
+        let v = self.enum_with_scope.value_by_name(name);
+        EnumValueGen::parse(v.proto, &self.type_name, v.rust_name().get())
+    }
+
+    pub fn write(&self, w: &mut CodeWriter) {
+        self.write_struct(w);
+        if self.allow_alias() {
+            w.write_line("");
+            self.write_impl_eq(w);
+            w.write_line("");
+            self.write_impl_hash(w);
+        }
+        w.write_line("");
+        self.write_impl_enum(w);
+        w.write_line("");
+        self.write_impl_copy(w);
+        w.write_line("");
+        self.write_impl_default(w);
+        w.write_line("");
+        self.write_impl_value(w);
+    }
+
+    fn write_struct(&self, w: &mut CodeWriter) {
+        let mut derive = Vec::new();
+        derive.push("Clone");
+        if !self.allow_alias() {
+            derive.push("PartialEq");
+        }
+        derive.push("Eq");
+        derive.push("Debug");
+        if !self.allow_alias() {
+            derive.push("Hash");
+        } else {
+            w.comment("Note: you cannot use pattern matching for enums with allow_alias option");
+        }
+        w.derive(&derive);
+        serde::write_serde_attr(w, &self.customize, "derive(Serialize, Deserialize)");
+        let ref type_name = self.type_name;
+        w.expr_block(&format!("pub enum {}", type_name), |w| {
+            for value in self.values_all() {
+                if self.allow_alias() {
+                    w.write_line(&format!(
+                        "{}, // {}",
+                        value.rust_name_inner(),
+                        value.number()
+                    ));
+                } else {
+                    w.write_line(&format!(
+                        "{} = {},",
+                        value.rust_name_inner(),
+                        value.number()
+                    ));
+                }
+            }
+        });
+    }
+
+    fn write_fn_value(&self, w: &mut CodeWriter) {
+        w.def_fn("value(&self) -> i32", |w| {
+            if self.allow_alias() {
+                w.match_expr("*self", |w| {
+                    for value in self.values_all() {
+                        w.case_expr(value.rust_name_outer(), format!("{}", value.number()));
+                    }
+                });
+            } else {
+                w.write_line("*self as i32")
+            }
+        });
+    }
+
+    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.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("");
+                w.def_fn(
+                    &format!(
+                        "enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor"
+                    ),
+                    |w| {
+                        w.lazy_static_decl_get(
+                            "descriptor",
+                            "::protobuf::reflect::EnumDescriptor",
+                            |w| {
+                                let ref type_name = self.type_name;
+                                w.write_line(&format!(
+                                    "::protobuf::reflect::EnumDescriptor::new_pb_name::<{}>(\"{}\", {})",
+                                    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(self.descriptor())"),
+            )
+        })
+    }
+
+    fn write_impl_copy(&self, w: &mut CodeWriter) {
+        w.impl_for_block("::std::marker::Copy", &self.type_name, |_w| {});
+    }
+
+    fn write_impl_eq(&self, w: &mut CodeWriter) {
+        assert!(self.allow_alias());
+        w.impl_for_block("::std::cmp::PartialEq", &self.type_name, |w| {
+            w.def_fn("eq(&self, other: &Self) -> bool", |w| {
+                w.write_line("self.value() == other.value()");
+            });
+        });
+    }
+
+    fn write_impl_hash(&self, w: &mut CodeWriter) {
+        assert!(self.allow_alias());
+        w.impl_for_block("::std::hash::Hash", &self.type_name, |w| {
+            w.def_fn("hash<H : ::std::hash::Hasher>(&self, state: &mut H)", |w| {
+                w.write_line("state.write_i32(self.value())");
+            });
+        });
+    }
+
+    fn write_impl_default(&self, w: &mut CodeWriter) {
+        let first_value = &self.enum_with_scope.values()[0];
+        if first_value.proto.get_number() != 0 {
+            // This warning is emitted only for proto2
+            // (because in proto3 first enum variant number is always 0).
+            // `Default` implemented unconditionally to simplify certain
+            // generic operations, e. g. reading a map.
+            // Also, note that even in proto2 some operations fallback to
+            // first enum value, e. g. `get_xxx` for unset field,
+            // so this implementation is not completely unreasonable.
+            w.comment("Note, `Default` is implemented although default value is not 0");
+        }
+        w.impl_for_block("::std::default::Default", &self.type_name, |w| {
+            w.def_fn("default() -> Self", |w| {
+                w.write_line(&format!(
+                    "{}::{}",
+                    &self.type_name,
+                    &first_value.rust_name()
+                ))
+            });
+        });
+    }
+}