164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Protocol Buffers - Google's data interchange format 264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Copyright 2008 Google Inc. All rights reserved. 364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// http://code.google.com/p/protobuf/ 464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// 564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Redistribution and use in source and binary forms, with or without 664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// modification, are permitted provided that the following conditions are 764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// met: 864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// 964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// * Redistributions of source code must retain the above copyright 1064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// notice, this list of conditions and the following disclaimer. 1164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// * Redistributions in binary form must reproduce the above 1264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// copyright notice, this list of conditions and the following disclaimer 1364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// in the documentation and/or other materials provided with the 1464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// distribution. 1564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// * Neither the name of Google Inc. nor the names of its 1664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// contributors may be used to endorse or promote products derived from 1764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// this software without specific prior written permission. 1864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// 1964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 3164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Author: kenton@google.com (Kenton Varda) 3264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Based on original Protocol Buffers design by 3364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Sanjay Ghemawat, Jeff Dean, and others. 3464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 3564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_params.h> 3664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_generator.h> 3764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_file.h> 3864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_helpers.h> 3964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/io/printer.h> 4064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/io/zero_copy_stream.h> 4164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/descriptor.pb.h> 4264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/strutil.h> 4364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 4464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace google { 4564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace protobuf { 4664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace compiler { 4764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace javanano { 4864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 4964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid UpdateParamsRecursively(Params& params, 5064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci const FileDescriptor* file) { 5164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Add any parameters for this file 5264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (file->options().has_java_outer_classname()) { 5364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci params.set_java_outer_classname( 5464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci file->name(), file->options().java_outer_classname()); 5564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 5664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (file->options().has_java_package()) { 5764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci params.set_java_package( 5864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci file->name(), file->options().java_package()); 5964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 608170787391efcb6cc6a8babc1cce35d5b1aff420Max Cai if (file->options().has_java_multiple_files()) { 618170787391efcb6cc6a8babc1cce35d5b1aff420Max Cai params.set_java_multiple_files( 628170787391efcb6cc6a8babc1cce35d5b1aff420Max Cai file->name(), file->options().java_multiple_files()); 638170787391efcb6cc6a8babc1cce35d5b1aff420Max Cai } 6464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 6564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Loop through all dependent files recursively 6664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // adding dep 6764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci for (int i = 0; i < file->dependency_count(); i++) { 6864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci UpdateParamsRecursively(params, file->dependency(i)); 6964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 7064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} 7164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 7264d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciJavaNanoGenerator::JavaNanoGenerator() {} 7364d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciJavaNanoGenerator::~JavaNanoGenerator() {} 7464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 7564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcibool JavaNanoGenerator::Generate(const FileDescriptor* file, 7664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci const string& parameter, 7764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci OutputDirectory* output_directory, 7864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci string* error) const { 7964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci vector<pair<string, string> > options; 8064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 8164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci ParseGeneratorParameter(parameter, &options); 8264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 8364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // ----------------------------------------------------------------- 8464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // parse generator options 8564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 8664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Name a file where we will write a list of generated file names, one 8764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // per line. 8864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci string output_list_file; 8964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci Params params(file->name()); 9064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 9164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Update per file params 9264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci UpdateParamsRecursively(params, file); 9364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 9464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Replace any existing options with ones from command line 9564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci for (int i = 0; i < options.size(); i++) { 9664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (options[i].first == "output_list_file") { 9764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci output_list_file = options[i].second; 9864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } else if (options[i].first == "java_package") { 9964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci vector<string> parts; 10064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci SplitStringUsing(options[i].second, "|", &parts); 10164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (parts.size() != 2) { 10264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci *error = "Bad java_package, expecting filename|PackageName found '" 10364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci + options[i].second + "'"; 10464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return false; 10564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 10664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci params.set_java_package(parts[0], parts[1]); 10764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } else if (options[i].first == "java_outer_classname") { 10864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci vector<string> parts; 10964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci SplitStringUsing(options[i].second, "|", &parts); 11064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (parts.size() != 2) { 11164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci *error = "Bad java_outer_classname, " 11264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci "expecting filename|ClassName found '" 11364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci + options[i].second + "'"; 11464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return false; 11564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 11664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci params.set_java_outer_classname(parts[0], parts[1]); 1170e055f079f53b07de3705838a7b4742ce56839f8Brian Duff } else if (options[i].first == "store_unknown_fields") { 1180e055f079f53b07de3705838a7b4742ce56839f8Brian Duff params.set_store_unknown_fields(options[i].second == "true"); 11964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } else if (options[i].first == "java_multiple_files") { 1208170787391efcb6cc6a8babc1cce35d5b1aff420Max Cai params.set_override_java_multiple_files(options[i].second == "true"); 12135d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci } else if (options[i].first == "java_nano_generate_has") { 12235d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci params.set_generate_has(options[i].second == "true"); 12364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } else { 12464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci *error = "Ignore unknown javanano generator option: " + options[i].first; 12564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 12664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 12764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 12864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // ----------------------------------------------------------------- 12964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 13064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci FileGenerator file_generator(file, params); 13164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (!file_generator.Validate(error)) { 13264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return false; 13364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 13464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 13564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci string package_dir = 13664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci StringReplace(file_generator.java_package(), ".", "/", true); 13764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (!package_dir.empty()) package_dir += "/"; 13864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 13964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci vector<string> all_files; 14064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 141624c448fbef20a1a2fad2289f622b468c25763d1Max Cai if (IsOuterClassNeeded(params, file)) { 142624c448fbef20a1a2fad2289f622b468c25763d1Max Cai string java_filename = package_dir; 143624c448fbef20a1a2fad2289f622b468c25763d1Max Cai java_filename += file_generator.classname(); 144624c448fbef20a1a2fad2289f622b468c25763d1Max Cai java_filename += ".java"; 145624c448fbef20a1a2fad2289f622b468c25763d1Max Cai all_files.push_back(java_filename); 146624c448fbef20a1a2fad2289f622b468c25763d1Max Cai 147624c448fbef20a1a2fad2289f622b468c25763d1Max Cai // Generate main java file. 148624c448fbef20a1a2fad2289f622b468c25763d1Max Cai scoped_ptr<io::ZeroCopyOutputStream> output( 149624c448fbef20a1a2fad2289f622b468c25763d1Max Cai output_directory->Open(java_filename)); 150624c448fbef20a1a2fad2289f622b468c25763d1Max Cai io::Printer printer(output.get(), '$'); 151624c448fbef20a1a2fad2289f622b468c25763d1Max Cai file_generator.Generate(&printer); 152624c448fbef20a1a2fad2289f622b468c25763d1Max Cai } 15364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 15464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Generate sibling files. 15564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci file_generator.GenerateSiblings(package_dir, output_directory, &all_files); 15664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 15764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Generate output list if requested. 15864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci if (!output_list_file.empty()) { 15964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // Generate output list. This is just a simple text file placed in a 16064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci // deterministic location which lists the .java files being generated. 16164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output( 16264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci output_directory->Open(output_list_file)); 16364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci io::Printer srclist_printer(srclist_raw_output.get(), '$'); 16464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci for (int i = 0; i < all_files.size(); i++) { 16564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci srclist_printer.Print("$filename$\n", "filename", all_files[i]); 16664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 16764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci } 16864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 16964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci return true; 17064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} 17164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci 17264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} // namespace java 17364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} // namespace compiler 17464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} // namespace protobuf 17564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci} // namespace google 176