javanano_generator.cc revision ccc48faf20dbf3b3cddcffe78d198876d543529b
183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// Protocol Buffers - Google's data interchange format
283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// Copyright 2008 Google Inc.  All rights reserved.
383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// http://code.google.com/p/protobuf/
483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com//
583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// Redistribution and use in source and binary forms, with or without
683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// modification, are permitted provided that the following conditions are
783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// met:
883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com//
983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com//     * Redistributions of source code must retain the above copyright
1009a5383adc59c3798f6f6e851f46320393b6c4b8scroggo@google.com// notice, this list of conditions and the following disclaimer.
1183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com//     * Redistributions in binary form must reproduce the above
128f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org// copyright notice, this list of conditions and the following disclaimer
1383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// in the documentation and/or other materials provided with the
1483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// distribution.
1583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com//     * Neither the name of Google Inc. nor the names of its
1683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// contributors may be used to endorse or promote products derived from
1783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// this software without specific prior written permission.
1883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com//
1974b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3074b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
3174b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org// Author: kenton@google.com (Kenton Varda)
3274b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org//  Based on original Protocol Buffers design by
3374b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org//  Sanjay Ghemawat, Jeff Dean, and others.
3474b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
3574b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/compiler/javanano/javanano_params.h>
3674b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/compiler/javanano/javanano_generator.h>
3774b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/compiler/javanano/javanano_file.h>
3874b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/compiler/javanano/javanano_helpers.h>
3974b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/io/printer.h>
4074b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/io/zero_copy_stream.h>
4174b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/descriptor.pb.h>
4274b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org#include <google/protobuf/stubs/strutil.h>
4374b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
4483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comnamespace google {
4583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comnamespace protobuf {
4683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comnamespace compiler {
4783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comnamespace javanano {
4883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
4983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comvoid UpdateParamsRecursively(Params& params,
5083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    const FileDescriptor* file) {
5183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Add any parameters for this file
5283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (file->options().has_java_outer_classname()) {
5383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    params.set_java_outer_classname(
5483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      file->name(), file->options().java_outer_classname());
5574b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  }
5683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (file->options().has_java_package()) {
5783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    params.set_java_package(
5883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      file->name(), file->options().java_package());
5983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  }
6083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (file->options().has_java_multiple_files()) {
6183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    params.set_java_multiple_files(
6283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      file->name(), file->options().java_multiple_files());
6383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  }
6483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
6583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Loop through all dependent files recursively
6683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // adding dep
6783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  for (int i = 0; i < file->dependency_count(); i++) {
6883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    UpdateParamsRecursively(params, file->dependency(i));
6983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  }
7083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com}
7183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
7283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comJavaNanoGenerator::JavaNanoGenerator() {}
7383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.comJavaNanoGenerator::~JavaNanoGenerator() {}
7483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
7583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.combool JavaNanoGenerator::Generate(const FileDescriptor* file,
7683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com                             const string& parameter,
7783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com                             OutputDirectory* output_directory,
7883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com                             string* error) const {
7983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  vector<pair<string, string> > options;
8083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
8183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  ParseGeneratorParameter(parameter, &options);
8274b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
8383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // -----------------------------------------------------------------
8483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // parse generator options
8583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
8683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Name a file where we will write a list of generated file names, one
8783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // per line.
8883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  string output_list_file;
8983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  Params params(file->name());
9083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
9183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Update per file params
9283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  UpdateParamsRecursively(params, file);
9383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
9483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Replace any existing options with ones from command line
9583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  for (int i = 0; i < options.size(); i++) {
9683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    if (options[i].first == "output_list_file") {
9783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      output_list_file = options[i].second;
9883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "java_package") {
9983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        vector<string> parts;
10083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        SplitStringUsing(options[i].second, "|", &parts);
10174b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org        if (parts.size() != 2) {
10283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com          *error = "Bad java_package, expecting filename|PackageName found '"
10383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com            + options[i].second + "'";
10483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com          return false;
10583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        }
10683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        params.set_java_package(parts[0], parts[1]);
10783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "java_outer_classname") {
10883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        vector<string> parts;
10983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        SplitStringUsing(options[i].second, "|", &parts);
11083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        if (parts.size() != 2) {
11183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com          *error = "Bad java_outer_classname, "
11283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com                   "expecting filename|ClassName found '"
11383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com                   + options[i].second + "'";
11483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com          return false;
11583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        }
11683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        params.set_java_outer_classname(parts[0], parts[1]);
11783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "store_unknown_fields") {
11883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_store_unknown_fields(options[i].second == "true");
11983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "java_multiple_files") {
12083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_override_java_multiple_files(options[i].second == "true");
12183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "java_nano_generate_has") {
12283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_generate_has(options[i].second == "true");
12383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "enum_style") {
12483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_java_enum_style(options[i].second == "java");
12583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "optional_field_style") {
12683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_optional_field_accessors(options[i].second == "accessors");
12783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_use_reference_types_for_primitives(options[i].second == "reftypes");
12883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else if (options[i].first == "generate_equals") {
12983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      params.set_generate_equals(options[i].second == "true");
13083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    } else {
13183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      *error = "Ignore unknown javanano generator option: " + options[i].first;
13283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    }
13383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  }
13483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
13583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Check illegal parameter combinations
13683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // Note: the enum-like optional_field_style generator param ensures
13783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // that we can never have illegal combinations of field styles
13883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // (e.g. reftypes and accessors can't be on at the same time).
13983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (params.generate_has()
14083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com      && (params.optional_field_accessors()
14183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com          || params.use_reference_types_for_primitives())) {
14283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    error->assign("java_nano_generate_has=true cannot be used in conjunction"
14383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com        " with optional_field_style=accessors or optional_field_style=reftypes");
14483fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    return false;
14583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  }
14683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
14783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  // -----------------------------------------------------------------
14883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
14983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  FileGenerator file_generator(file, params);
15083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (!file_generator.Validate(error)) {
15183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    return false;
15283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  }
15383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
15474b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  string package_dir =
15583fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    StringReplace(file_generator.java_package(), ".", "/", true);
15683fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (!package_dir.empty()) package_dir += "/";
15783fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
15883fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  vector<string> all_files;
15983fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com
16083fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com  if (IsOuterClassNeeded(params, file)) {
16183fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    string java_filename = package_dir;
16283fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    java_filename += file_generator.classname();
16383fd2c7c43fea7ea49adc68681e9ed3ed180d568scroggo@google.com    java_filename += ".java";
16474b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    all_files.push_back(java_filename);
16574b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
16674b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    // Generate main java file.
16774b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    scoped_ptr<io::ZeroCopyOutputStream> output(
16874b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org      output_directory->Open(java_filename));
16974b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    io::Printer printer(output.get(), '$');
17074b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    file_generator.Generate(&printer);
17174b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  }
17274b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
17374b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  // Generate sibling files.
17474b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  file_generator.GenerateSiblings(package_dir, output_directory, &all_files);
17574b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
17674b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  // Generate output list if requested.
17774b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  if (!output_list_file.empty()) {
17874b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    // Generate output list.  This is just a simple text file placed in a
17974b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    // deterministic location which lists the .java files being generated.
18074b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
18174b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org      output_directory->Open(output_list_file));
18274b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    io::Printer srclist_printer(srclist_raw_output.get(), '$');
18374b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    for (int i = 0; i < all_files.size(); i++) {
18474b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org      srclist_printer.Print("$filename$\n", "filename", all_files[i]);
18574b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org    }
18674b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  }
18774b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
18874b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org  return true;
18974b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org}
19074b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org
19174b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org}  // namespace java
19274b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org}  // namespace compiler
19374b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org}  // namespace protobuf
19474b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org}  // namespace google
19574b88b70b8f78e09d223e3f8357e18e6043fa3aacommit-bot@chromium.org