15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/java/java_file.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/java/java_enum.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/java/java_service.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/java/java_extension.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/java/java_helpers.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/java/java_message.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/code_generator.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h> 45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/dynamic_message.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace java { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Recursively searches the given message to collect extensions. 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Returns true if all the extensions can be recognized. The extensions will be 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// appended in to the extensions parameter. 59ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Returns false when there are unknown fields, in which case the data in the 60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// extensions output parameter is not reliable and should be discarded. 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool CollectExtensions(const Message& message, 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<const FieldDescriptor*>* extensions) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection = message.GetReflection(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // There are unknown fields that could be extensions, thus this call fails. 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (reflection->GetUnknownFields(message).field_count() > 0) return false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*> fields; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->ListFields(message, &fields); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < fields.size(); i++) { 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (fields[i]->is_extension()) extensions->push_back(fields[i]); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fields[i]->is_repeated()) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = reflection->FieldSize(message, fields[i]); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < size; j++) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& sub_message = 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetRepeatedMessage(message, fields[i], j); 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!CollectExtensions(sub_message, extensions)) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& sub_message = reflection->GetMessage(message, fields[i]); 84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!CollectExtensions(sub_message, extensions)) return false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 92ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Finds all extensions in the given message and its sub-messages. If the 93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// message contains unknown fields (which could be extensions), then those 94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// extensions are defined in alternate_pool. 95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// The message will be converted to a DynamicMessage backed by alternate_pool 96ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// in order to handle this case. 97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid CollectExtensions(const FileDescriptorProto& file_proto, 98ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const DescriptorPool& alternate_pool, 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<const FieldDescriptor*>* extensions, 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const string& file_data) { 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!CollectExtensions(file_proto, extensions)) { 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // There are unknown fields in the file_proto, which are probably 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // extensions. We need to parse the data into a dynamic message based on the 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // builder-pool to find out all extensions. 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName( 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_proto.GetDescriptor()->full_name()); 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(file_proto_desc) 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << "Find unknown fields in FileDescriptorProto when building " 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << file_proto.name() 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << ". It's likely that those fields are custom options, however, " 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "descriptor.proto is not in the transitive dependencies. " 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "This normally should not happen. Please report a bug."; 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DynamicMessageFactory factory; 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<Message> dynamic_file_proto( 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch factory.GetPrototype(file_proto_desc)->New()); 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(dynamic_file_proto.get() != NULL); 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data)); 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Collect the extensions again from the dynamic message. There should be no 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // more unknown fields this time, i.e. all the custom options should be 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // parsed as extensions now. 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extensions->clear(); 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions)) 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << "Find unknown fields in FileDescriptorProto when building " 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << file_proto.name() 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << ". It's likely that those fields are custom options, however, " 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "those options cannot be recognized in the builder pool. " 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "This normally should not happen. Please report a bug."; 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileGenerator::FileGenerator(const FileDescriptor* file) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : file_(file), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) java_package_(FileJavaPackage(file)), 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) classname_(FileClassName(file)) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileGenerator::~FileGenerator() {} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileGenerator::Validate(string* error) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that no class name matches the file's class name. This is a common 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // problem that leads to Java compile errors that can be hard to understand. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's especially bad when using the java_multiple_files, since we would 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // end up overwriting the outer class with one of the inner ones. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found_conflict = false; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->enum_type_count() && !found_conflict; i++) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_->enum_type(i)->name() == classname_) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_conflict = true; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count() && !found_conflict; i++) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_->message_type(i)->name() == classname_) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_conflict = true; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->service_count() && !found_conflict; i++) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_->service(i)->name() == classname_) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_conflict = true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found_conflict) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error->assign(file_->name()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error->append( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ": Cannot generate Java output because the file's outer class name, \""); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error->append(classname_); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error->append( 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\", matches the name of one of the types declared inside it. " 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Please either rename the type or use the java_outer_classname " 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "option to specify a different outer class name for the .proto file."); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::Generate(io::Printer* printer) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't import anything because we refer to all classes by their 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fully-qualified names in the generated source. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// source: $filename$\n" 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "filename", file_->name()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!java_package_.empty()) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "package $package$;\n" 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "package", java_package_); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "public final class $classname$ {\n" 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " private $classname$() {}\n", 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "classname", classname_); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "public static void registerAllExtensions(\n" 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n", 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "lite", HasDescriptorMethods(file_) ? "" : "Lite"); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->extension_count(); i++) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionGenerator(file_->extension(i)).GenerateRegistrationCode(printer); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); i++) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageGenerator(file_->message_type(i)) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateExtensionRegistrationCode(printer); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_->options().java_multiple_files()) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->enum_type_count(); i++) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumGenerator(file_->enum_type(i)).Generate(printer); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); i++) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageGenerator messageGenerator(file_->message_type(i)); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) messageGenerator.GenerateInterface(printer); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) messageGenerator.Generate(printer); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGenericServices(file_)) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->service_count(); i++) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceGenerator(file_->service(i)).Generate(printer); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extensions must be generated in the outer class since they are values, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not classes. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->extension_count(); i++) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionGenerator(file_->extension(i)).Generate(printer); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Static variables. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); i++) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Reuse MessageGenerator objects? 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageGenerator(file_->message_type(i)).GenerateStaticVariables(printer); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n"); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasDescriptorMethods(file_)) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateEmbeddedDescriptor(printer); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static {\n"); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); i++) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Reuse MessageGenerator objects? 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageGenerator(file_->message_type(i)) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateStaticVariableInitializers(printer); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// @@protoc_insertion_point(outer_class_scope)\n"); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("}\n"); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Embed the descriptor. We simply serialize the entire FileDescriptorProto 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and embed it as a string literal, which is parsed and built into real 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptors at initialization time. We unfortunately have to put it in 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a string literal, not a byte array, because apparently using a literal 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // byte array causes the Java compiler to generate *instructions* to 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialize each and every byte of the array, e.g. as if you typed: 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // b[0] = 123; b[1] = 456; b[2] = 789; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This makes huge bytecode files and can easily hit the compiler's internal 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code size limits (error "code to large"). String literals are apparently 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // embedded raw, which is what we want. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorProto file_proto; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->CopyTo(&file_proto); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string file_data; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_proto.SerializeToString(&file_data); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "public static com.google.protobuf.Descriptors.FileDescriptor\n" 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " getDescriptor() {\n" 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " return descriptor;\n" 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n" 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "private static com.google.protobuf.Descriptors.FileDescriptor\n" 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " descriptor;\n" 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static {\n" 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " java.lang.String[] descriptorData = {\n"); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only write 40 bytes per line. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBytesPerLine = 40; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_data.size(); i += kBytesPerLine) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Every 400 lines, start a new string literal, in order to avoid the 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 64k length limit. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i % 400 == 0) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(",\n"); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print(" +\n"); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\"$data$\"", 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "data", CEscape(file_data.substr(i, kBytesPerLine))); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n};\n"); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the InternalDescriptorAssigner. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "com.google.protobuf.Descriptors.FileDescriptor." 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "InternalDescriptorAssigner assigner =\n" 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " new com.google.protobuf.Descriptors.FileDescriptor." 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "InternalDescriptorAssigner() {\n" 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " public com.google.protobuf.ExtensionRegistry assignDescriptors(\n" 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " com.google.protobuf.Descriptors.FileDescriptor root) {\n" 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " descriptor = root;\n"); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Indent(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); i++) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Reuse MessageGenerator objects? 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageGenerator(file_->message_type(i)) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateStaticVariableInitializers(printer); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->extension_count(); i++) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Reuse ExtensionGenerator objects? 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionGenerator(file_->extension(i)) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .GenerateNonNestedInitializationCode(printer); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 356ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Proto compiler builds a DescriptorPool, which holds all the descriptors to 357ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // generate, when processing the ".proto" files. We call this DescriptorPool 358ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the parsed pool (a.k.a. file_->pool()). 359ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 360ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Note that when users try to extend the (.*)DescriptorProto in their 361ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // ".proto" files, it does not affect the pre-built FileDescriptorProto class 362ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // in proto compiler. When we put the descriptor data in the file_proto, those 363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // extensions become unknown fields. 364ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Now we need to find out all the extension value to the (.*)DescriptorProto 366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // in the file_proto message, and prepare an ExtensionRegistry to return. 367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // To find those extensions, we need to parse the data into a dynamic message 369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // of the FileDescriptor based on the builder-pool, then we can use 370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // reflections to find all extension fields 371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<const FieldDescriptor*> extensions; 372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); 373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (extensions.size() > 0) { 375ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Must construct an ExtensionRegistry containing all existing extensions 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and return it. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "com.google.protobuf.ExtensionRegistry registry =\n" 379ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " com.google.protobuf.ExtensionRegistry.newInstance();\n"); 380ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < extensions.size(); i++) { 381ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ExtensionGenerator(extensions[i]).GenerateRegistrationCode(printer); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return registry;\n"); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return null;\n"); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }\n" 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " };\n"); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoke internalBuildGeneratedFileFrom() to build the file. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "com.google.protobuf.Descriptors.FileDescriptor\n" 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " .internalBuildGeneratedFileFrom(descriptorData,\n" 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " new com.google.protobuf.Descriptors.FileDescriptor[] {\n"); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->dependency_count(); i++) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldIncludeDependency(file_->dependency(i))) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " $dependency$.getDescriptor(),\n", 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dependency", ClassName(file_->dependency(i))); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " }, assigner);\n"); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Outdent(); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "}\n"); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename GeneratorClass, typename DescriptorClass> 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void GenerateSibling(const string& package_dir, 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& java_package, 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorClass* descriptor, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GeneratorContext* context, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string>* file_list, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name_suffix, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (GeneratorClass::*pfn)(io::Printer* printer)) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string filename = package_dir + descriptor->name() + name_suffix + ".java"; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_list->push_back(filename); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Printer printer(output.get(), '$'); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.Print( 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" 438ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "// source: $filename$\n" 439ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "\n", 440ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "filename", descriptor->file()->name()); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!java_package.empty()) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.Print( 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "package $package$;\n" 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n", 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "package", java_package); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GeneratorClass generator(descriptor); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (generator.*pfn)(&printer); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateSiblings(const string& package_dir, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GeneratorContext* context, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string>* file_list) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file_->options().java_multiple_files()) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->enum_type_count(); i++) { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSibling<EnumGenerator>(package_dir, java_package_, 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->enum_type(i), 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context, file_list, "", 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &EnumGenerator::Generate); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); i++) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSibling<MessageGenerator>(package_dir, java_package_, 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->message_type(i), 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context, file_list, "OrBuilder", 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageGenerator::GenerateInterface); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSibling<MessageGenerator>(package_dir, java_package_, 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->message_type(i), 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context, file_list, "", 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageGenerator::Generate); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGenericServices(file_)) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->service_count(); i++) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateSibling<ServiceGenerator>(package_dir, java_package_, 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->service(i), 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context, file_list, "", 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ServiceGenerator::Generate); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace java 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace compiler 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 491