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 (HasDescriptorMethods(descriptor_->file())) {
    122     // Non-lite extensions
    123     if (descriptor_->extension_scope() == NULL) {
    124       // Non-nested
    125       printer->Print(
    126           vars,
    127           "public static final\n"
    128           "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
    129           "    $containing_type$,\n"
    130           "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
    131           "        .newFileScopedGeneratedExtension(\n"
    132           "      $singular_type$.class,\n"
    133           "      $prototype$);\n");
    134     } else {
    135       // Nested
    136       printer->Print(
    137           vars,
    138           "public static final\n"
    139           "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
    140           "    $containing_type$,\n"
    141           "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
    142           "        .newMessageScopedGeneratedExtension(\n"
    143           "      $scope$.getDefaultInstance(),\n"
    144           "      $index$,\n"
    145           "      $singular_type$.class,\n"
    146           "      $prototype$);\n");
    147     }
    148   } else {
    149     // Lite extensions
    150     if (descriptor_->is_repeated()) {
    151       printer->Print(
    152           vars,
    153           "public static final\n"
    154           "  com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
    155           "    $containing_type$,\n"
    156           "    $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
    157           "        .newRepeatedGeneratedExtension(\n"
    158           "      $containing_type$.getDefaultInstance(),\n"
    159           "      $prototype$,\n"
    160           "      $enum_map$,\n"
    161           "      $number$,\n"
    162           "      com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
    163           "      $packed$,\n"
    164           "      $singular_type$.class);\n");
    165     } else {
    166       printer->Print(
    167           vars,
    168           "public static final\n"
    169           "  com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
    170           "    $containing_type$,\n"
    171           "    $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
    172           "        .newSingularGeneratedExtension(\n"
    173           "      $containing_type$.getDefaultInstance(),\n"
    174           "      $default$,\n"
    175           "      $prototype$,\n"
    176           "      $enum_map$,\n"
    177           "      $number$,\n"
    178           "      com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
    179           "      $singular_type$.class);\n");
    180     }
    181   }
    182 }
    183 
    184 void ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
    185     io::Printer* printer) {
    186   if (descriptor_->extension_scope() == NULL &&
    187       HasDescriptorMethods(descriptor_->file())) {
    188     // Only applies to non-nested, non-lite extensions.
    189     printer->Print(
    190         "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
    191         "name", UnderscoresToCamelCase(descriptor_),
    192         "index", SimpleItoa(descriptor_->index()));
    193   }
    194 }
    195 
    196 void ImmutableExtensionGenerator::GenerateRegistrationCode(
    197     io::Printer* printer) {
    198   printer->Print(
    199     "registry.add($scope$.$name$);\n",
    200     "scope", scope_,
    201     "name", UnderscoresToCamelCase(descriptor_));
    202 }
    203 
    204 }  // namespace java
    205 }  // namespace compiler
    206 }  // namespace protobuf
    207 }  // namespace google
    208