Home | History | Annotate | Download | only in java
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 
     35 #include <google/protobuf/compiler/java/java_extension.h>
     36 
     37 #include <google/protobuf/compiler/java/java_context.h>
     38 #include <google/protobuf/compiler/java/java_doc_comment.h>
     39 #include <google/protobuf/compiler/java/java_helpers.h>
     40 #include <google/protobuf/compiler/java/java_name_resolver.h>
     41 #include <google/protobuf/io/printer.h>
     42 #include <google/protobuf/stubs/strutil.h>
     43 
     44 namespace google {
     45 namespace protobuf {
     46 namespace compiler {
     47 namespace java {
     48 
     49 ImmutableExtensionGenerator::ImmutableExtensionGenerator(
     50     const FieldDescriptor* descriptor, Context* context)
     51   : descriptor_(descriptor), context_(context),
     52     name_resolver_(context->GetNameResolver()) {
     53   if (descriptor_->extension_scope() != NULL) {
     54     scope_ = name_resolver_->GetImmutableClassName(
     55         descriptor_->extension_scope());
     56   } else {
     57     scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
     58   }
     59 }
     60 
     61 ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {}
     62 
     63 // Initializes the vars referenced in the generated code templates.
     64 void ExtensionGenerator::InitTemplateVars(const FieldDescriptor* descriptor,
     65                                           const string& scope,
     66                                           bool immutable,
     67                                           ClassNameResolver* name_resolver,
     68                                           map<string, string>* vars_pointer) {
     69   map<string, string> &vars = *vars_pointer;
     70   vars["scope"] = scope;
     71   vars["name"] = UnderscoresToCamelCase(descriptor);
     72   vars["containing_type"] =
     73       name_resolver->GetClassName(descriptor->containing_type(), immutable);
     74   vars["number"] = SimpleItoa(descriptor->number());
     75   vars["constant_name"] = FieldConstantName(descriptor);
     76   vars["index"] = SimpleItoa(descriptor->index());
     77   vars["default"] = descriptor->is_repeated() ?
     78       "" : DefaultValue(descriptor, immutable, name_resolver);
     79   vars["type_constant"] = FieldTypeName(GetType(descriptor));
     80   vars["packed"] = descriptor->options().packed() ? "true" : "false";
     81   vars["enum_map"] = "null";
     82   vars["prototype"] = "null";
     83 
     84   JavaType java_type = GetJavaType(descriptor);
     85   string singular_type;
     86   switch (java_type) {
     87     case JAVATYPE_MESSAGE:
     88       singular_type = name_resolver->GetClassName(descriptor->message_type(),
     89                                                    immutable);
     90       vars["prototype"] = singular_type + ".getDefaultInstance()";
     91       break;
     92     case JAVATYPE_ENUM:
     93       singular_type = name_resolver->GetClassName(descriptor->enum_type(),
     94                                                    immutable);
     95       vars["enum_map"] = singular_type + ".internalGetValueMap()";
     96       break;
     97     case JAVATYPE_STRING:
     98       singular_type = "java.lang.String";
     99       break;
    100     case JAVATYPE_BYTES:
    101       singular_type = immutable ? "com.google.protobuf.ByteString" : "byte[]";
    102       break;
    103     default:
    104       singular_type = BoxedPrimitiveTypeName(java_type);
    105       break;
    106   }
    107   vars["type"] = descriptor->is_repeated() ?
    108       "java.util.List<" + singular_type + ">" : singular_type;
    109   vars["singular_type"] = singular_type;
    110 }
    111 
    112 void ImmutableExtensionGenerator::Generate(io::Printer* printer) {
    113   map<string, string> vars;
    114   const bool kUseImmutableNames = true;
    115   InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_,
    116                    &vars);
    117   printer->Print(vars,
    118       "public static final int $constant_name$ = $number$;\n");
    119 
    120   WriteFieldDocComment(printer, descriptor_);
    121   if (descriptor_->extension_scope() == NULL) {
    122     // Non-nested
    123     printer->Print(
    124         vars,
    125         "public static final\n"
    126         "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
    127         "    $containing_type$,\n"
    128         "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
    129         "        .newFileScopedGeneratedExtension(\n"
    130         "      $singular_type$.class,\n"
    131         "      $prototype$);\n");
    132   } else {
    133     // Nested
    134     printer->Print(
    135         vars,
    136         "public static final\n"
    137         "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
    138         "    $containing_type$,\n"
    139         "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
    140         "        .newMessageScopedGeneratedExtension(\n"
    141         "      $scope$.getDefaultInstance(),\n"
    142         "      $index$,\n"
    143         "      $singular_type$.class,\n"
    144         "      $prototype$);\n");
    145   }
    146 }
    147 
    148 int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
    149     io::Printer* printer) {
    150   int bytecode_estimate = 0;
    151   if (descriptor_->extension_scope() == NULL) {
    152     // Only applies to non-nested extensions.
    153     printer->Print(
    154         "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
    155         "name", UnderscoresToCamelCase(descriptor_),
    156         "index", SimpleItoa(descriptor_->index()));
    157     bytecode_estimate += 21;
    158   }
    159   return bytecode_estimate;
    160 }
    161 
    162 int ImmutableExtensionGenerator::GenerateRegistrationCode(
    163     io::Printer* printer) {
    164   printer->Print(
    165     "registry.add($scope$.$name$);\n",
    166     "scope", scope_,
    167     "name", UnderscoresToCamelCase(descriptor_));
    168   return 7;
    169 }
    170 
    171 }  // namespace java
    172 }  // namespace compiler
    173 }  // namespace protobuf
    174 }  // namespace google
    175