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/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..1f91285
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,277 @@
+//! This crate implement protobuf codegen.
+//!
+//! This crate:
+//! * provides `protoc-gen-rust` plugin for `protoc` command
+//! * implement protobuf codegen
+//!
+//! This crate is not meant to be used directly, in fact, it does not provide any public API
+//! (except for `protoc-gen-rust` binary).
+//!
+//! Code can be generated with either:
+//! * `protoc-gen-rust` binary or
+//! * `protoc-rust` crate (codegen which depends on `protoc` binary for parsing)
+//! * `protobuf-codegen-pure` crate
+
+#![deny(intra_doc_link_resolution_failure)]
+#![deny(missing_docs)]
+
+extern crate protobuf;
+
+use std::collections::hash_map::HashMap;
+use std::fmt::Write as FmtWrite;
+use std::fs::File;
+use std::io;
+use std::io::Write;
+use std::path::Path;
+
+use protobuf::compiler_plugin;
+use protobuf::descriptor::*;
+use protobuf::Message;
+
+mod customize;
+mod enums;
+mod extensions;
+mod field;
+mod file;
+mod file_and_mod;
+mod file_descriptor;
+#[doc(hidden)]
+pub mod float;
+mod inside;
+mod message;
+mod oneof;
+mod protobuf_name;
+mod rust_name;
+mod rust_types_values;
+mod serde;
+mod well_known_types;
+
+pub(crate) mod rust;
+pub(crate) mod scope;
+pub(crate) mod strx;
+pub(crate) mod syntax;
+
+use customize::customize_from_rustproto_for_file;
+#[doc(hidden)]
+pub use customize::Customize;
+
+pub mod code_writer;
+
+use self::code_writer::CodeWriter;
+use self::enums::*;
+use self::extensions::*;
+use self::message::*;
+use file::proto_path_to_rust_mod;
+use inside::protobuf_crate_path;
+use scope::FileScope;
+use scope::RootScope;
+
+fn escape_byte(s: &mut String, b: u8) {
+    if b == b'\n' {
+        write!(s, "\\n").unwrap();
+    } else if b == b'\r' {
+        write!(s, "\\r").unwrap();
+    } else if b == b'\t' {
+        write!(s, "\\t").unwrap();
+    } else if b == b'\\' || b == b'"' {
+        write!(s, "\\{}", b as char).unwrap();
+    } else if b == b'\0' {
+        write!(s, "\\0").unwrap();
+    // ASCII printable except space
+    } else if b > 0x20 && b < 0x7f {
+        write!(s, "{}", b as char).unwrap();
+    } else {
+        write!(s, "\\x{:02x}", b).unwrap();
+    }
+}
+
+fn write_file_descriptor_data(
+    file: &FileDescriptorProto,
+    customize: &Customize,
+    w: &mut CodeWriter,
+) {
+    let fdp_bytes = file.write_to_bytes().unwrap();
+    w.write_line("static file_descriptor_proto_data: &'static [u8] = b\"\\");
+    w.indented(|w| {
+        const MAX_LINE_LEN: usize = 72;
+
+        let mut s = String::new();
+        for &b in &fdp_bytes {
+            let prev_len = s.len();
+            escape_byte(&mut s, b);
+            let truncate = s.len() > MAX_LINE_LEN;
+            if truncate {
+                s.truncate(prev_len);
+            }
+            if truncate || s.len() == MAX_LINE_LEN {
+                write!(s, "\\").unwrap();
+                w.write_line(&s);
+                s.clear();
+            }
+            if truncate {
+                escape_byte(&mut s, b);
+            }
+        }
+        if !s.is_empty() {
+            write!(s, "\\").unwrap();
+            w.write_line(&s);
+            s.clear();
+        }
+    });
+    w.write_line("\";");
+    w.write_line("");
+    w.lazy_static_protobuf_path(
+        "file_descriptor_proto_lazy",
+        &format!(
+            "{}::descriptor::FileDescriptorProto",
+            protobuf_crate_path(customize)
+        ),
+        protobuf_crate_path(customize),
+    );
+    w.write_line("");
+    w.def_fn(
+        "parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto",
+        |w| {
+            w.write_line("::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap()");
+        },
+    );
+    w.write_line("");
+    w.pub_fn(
+        "file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto",
+        |w| {
+            w.unsafe_expr(|w| {
+                w.block("file_descriptor_proto_lazy.get(|| {", "})", |w| {
+                    w.write_line("parse_descriptor_proto()");
+                });
+            });
+        },
+    );
+}
+
+fn gen_file(
+    file: &FileDescriptorProto,
+    _files_map: &HashMap<&str, &FileDescriptorProto>,
+    root_scope: &RootScope,
+    customize: &Customize,
+) -> Option<compiler_plugin::GenResult> {
+    // TODO: use it
+    let mut customize = customize.clone();
+    // options specified in invocation have precedence over options specified in file
+    customize.update_with(&customize_from_rustproto_for_file(file.get_options()));
+
+    let scope = FileScope {
+        file_descriptor: file,
+    }
+    .to_scope();
+    let lite_runtime = customize.lite_runtime.unwrap_or_else(|| {
+        file.get_options().get_optimize_for() == FileOptions_OptimizeMode::LITE_RUNTIME
+    });
+
+    let mut v = Vec::new();
+
+    {
+        let mut w = CodeWriter::new(&mut v);
+
+        // Hack: hard code version number here because Android.bp
+        // rust modules cannot pass it though env variable yet.
+        w.write_generated_by("rust-protobuf", "2.14.0");
+        w.write_line(&format!("//! Generated file from `{}`", file.get_name()));
+
+        w.write_line("");
+        w.write_line("use protobuf::Message as Message_imported_for_functions;");
+        w.write_line("use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions;");
+        if customize.inside_protobuf != Some(true) {
+            w.write_line("");
+            w.write_line("/// Generated files are compatible only with the same version");
+            w.write_line("/// of protobuf runtime.");
+            w.commented(|w| {
+                w.write_line(&format!(
+                    "const _PROTOBUF_VERSION_CHECK: () = {}::{};",
+                    protobuf_crate_path(&customize),
+                    protobuf::VERSION_IDENT
+                ));
+            })
+        }
+
+        for message in &scope.get_messages() {
+            // ignore map entries, because they are not used in map fields
+            if message.map_entry().is_none() {
+                w.write_line("");
+                MessageGen::new(message, &root_scope, &customize).write(&mut w);
+            }
+        }
+        for enum_type in &scope.get_enums() {
+            w.write_line("");
+            EnumGen::new(enum_type, file, &customize, root_scope).write(&mut w);
+        }
+
+        write_extensions(file, &root_scope, &mut w, &customize);
+
+        if !lite_runtime {
+            w.write_line("");
+            write_file_descriptor_data(file, &customize, &mut w);
+        }
+    }
+
+    Some(compiler_plugin::GenResult {
+        name: format!("{}.rs", proto_path_to_rust_mod(file.get_name())),
+        content: v,
+    })
+}
+
+// This function is also used externally by cargo plugin
+// https://github.com/plietar/rust-protobuf-build
+// So be careful changing its signature.
+#[doc(hidden)]
+pub fn gen(
+    file_descriptors: &[FileDescriptorProto],
+    files_to_generate: &[String],
+    customize: &Customize,
+) -> Vec<compiler_plugin::GenResult> {
+    let root_scope = RootScope {
+        file_descriptors: file_descriptors,
+    };
+
+    let mut results: Vec<compiler_plugin::GenResult> = Vec::new();
+    let files_map: HashMap<&str, &FileDescriptorProto> =
+        file_descriptors.iter().map(|f| (f.get_name(), f)).collect();
+
+    let all_file_names: Vec<&str> = file_descriptors.iter().map(|f| f.get_name()).collect();
+
+    for file_name in files_to_generate {
+        let file = files_map.get(&file_name[..]).expect(&format!(
+            "file not found in file descriptors: {:?}, files: {:?}",
+            file_name, all_file_names
+        ));
+        results.extend(gen_file(file, &files_map, &root_scope, customize));
+    }
+    results
+}
+
+#[doc(hidden)]
+pub fn gen_and_write(
+    file_descriptors: &[FileDescriptorProto],
+    files_to_generate: &[String],
+    out_dir: &Path,
+    customize: &Customize,
+) -> io::Result<()> {
+    let results = gen(file_descriptors, files_to_generate, customize);
+
+    for r in &results {
+        let mut file_path = out_dir.to_owned();
+        file_path.push(&r.name);
+        let mut file_writer = File::create(&file_path)?;
+        file_writer.write_all(&r.content)?;
+        file_writer.flush()?;
+    }
+
+    Ok(())
+}
+
+#[doc(hidden)]
+pub fn protoc_gen_rust_main() {
+    compiler_plugin::plugin_main_2(|r| {
+        let customize = Customize::parse_from_parameter(r.parameter).expect("parse options");
+        gen(r.file_descriptors, r.files_to_generate, &customize)
+    });
+}