Home | History | Annotate | Download | only in java
      1 Protocol Buffers - Google's data interchange format
      2 Copyright 2008 Google Inc.
      3 
      4 This directory contains the Java Protocol Buffers runtime library.
      5 
      6 Installation - With Maven
      7 =========================
      8 
      9 The Protocol Buffers build is managed using Maven.  If you would
     10 rather build without Maven, see below.
     11 
     12 1) Install Apache Maven if you don't have it:
     13 
     14      http://maven.apache.org/
     15 
     16 2) Build the C++ code, or obtain a binary distribution of protoc.  If
     17    you install a binary distribution, make sure that it is the same
     18    version as this package.  If in doubt, run:
     19 
     20      $ protoc --version
     21 
     22    You will need to place the protoc executable in ../src.  (If you
     23    built it yourself, it should already be there.)
     24 
     25 3) Run the tests:
     26 
     27      $ mvn test
     28 
     29    If some tests fail, this library may not work correctly on your
     30    system.  Continue at your own risk.
     31 
     32 4) Install the library into your Maven repository:
     33 
     34      $ mvn install
     35 
     36 5) If you do not use Maven to manage your own build, you can build a
     37    .jar file to use:
     38 
     39      $ mvn package
     40 
     41    The .jar will be placed in the "target" directory.
     42 
     43 Installation - 'Lite' Version - With Maven
     44 ==========================================
     45 
     46 Building the 'lite' version of the Java Protocol Buffers library is
     47 the same as building the full version, except that all commands are
     48 run using the 'lite' profile.  (see
     49 http://maven.apache.org/guides/introduction/introduction-to-profiles.html)
     50 
     51 E.g. to install the lite version of the jar, you would run:
     52 
     53   $ mvn install -P lite
     54 
     55 The resulting artifact has the 'lite' classifier.  To reference it
     56 for dependency resolution, you would specify it as:
     57 
     58   <dependency>
     59     <groupId>com.google.protobuf</groupId>
     60     <artifactId>protobuf-java</artifactId>
     61     <version>${version}</version>
     62     <classifier>lite</classifier>
     63   </dependency>
     64 
     65 Installation - Without Maven
     66 ============================
     67 
     68 If you would rather not install Maven to build the library, you may
     69 follow these instructions instead.  Note that these instructions skip
     70 running unit tests.
     71 
     72 1) Build the C++ code, or obtain a binary distribution of protoc.  If
     73    you install a binary distribution, make sure that it is the same
     74    version as this package.  If in doubt, run:
     75 
     76      $ protoc --version
     77 
     78    If you built the C++ code without installing, the compiler binary
     79    should be located in ../src.
     80 
     81 2) Invoke protoc to build DescriptorProtos.java:
     82 
     83      $ protoc --java_out=src/main/java -I../src \
     84          ../src/google/protobuf/descriptor.proto
     85 
     86 3) Compile the code in src/main/java using whatever means you prefer.
     87 
     88 4) Install the classes wherever you prefer.
     89 
     90 Micro version
     91 ============================
     92 
     93 The runtime and generated code for MICRO_RUNTIME is smaller
     94 because it does not include support for the descriptor and
     95 reflection, and enums are generated as integer constants in
     96 the parent message or the file's outer class, with no
     97 protection against invalid values set to enum fields. Also,
     98 not currently supported are packed repeated elements or
     99 extensions.
    100 
    101 To create a jar file for the runtime and run tests invoke
    102 "mvn package -P micro" from the <protobuf-root>/java
    103 directory. The generated jar file is
    104 <protobuf-root>java/target/protobuf-java-2.2.0-micro.jar.
    105 
    106 If you wish to compile the MICRO_RUNTIME your self, place
    107 the 7 files below, in <root>/com/google/protobuf and
    108 create a jar file for use with your code and the generated
    109 code:
    110 
    111 ByteStringMicro.java
    112 CodedInputStreamMicro.java
    113 CodedOutputStreamMicro.java
    114 InvalidProtocolBufferException.java
    115 MessageMicro.java
    116 WireFormatMicro.java
    117 
    118 If you wish to change on the code generator it is located
    119 in /src/google/protobuf/compiler/javamicro.
    120 
    121 To generate code for the MICRO_RUNTIME invoke protoc with
    122 --javamicro_out command line parameter. javamicro_out takes
    123 a series of optional sub-parameters separated by commas
    124 and a final parameter, with a colon separator, which defines
    125 the source directory. Sub-parameters begin with a name
    126 followed by an equal and if that sub-parameter has multiple
    127 parameters they are seperated by "|". The command line options
    128 are:
    129 
    130 opt                  -> speed or space
    131 java_use_vector      -> true or false
    132 java_package         -> <file-name>|<package-name>
    133 java_outer_classname -> <file-name>|<package-name>
    134 java_multiple_files  -> true or false
    135 
    136 opt={speed,space} (default: space)
    137   This changes the code generation to optimize for speed or
    138   space. When opt=speed this changes the code generation
    139   for strings so that multiple conversions to Utf8 are
    140   eliminated.
    141 
    142 java_use_vector={true,false} (default: false)
    143   This specifies the collection class for repeated elements.
    144   If false, repeated elements use java.util.ArrayList<> and
    145   the code must be compiled with Java 1.5 or above. If true,
    146   repeated elements use java.util.Vector and the code can
    147   be compiled with Java 1.3 or above. The 'source'
    148   parameter of 'javac' may be used to control the version
    149   of the source: "javac -source 1.3". You can also change
    150   the <source> xml element for the maven-compiler-plugin.
    151   Below is for 1.5 sources:
    152 
    153       <plugin>
    154         <artifactId>maven-compiler-plugin</artifactId>
    155         <configuration>
    156           <source>1.5</source>
    157           <target>1.5</target>
    158         </configuration>
    159       </plugin>
    160 
    161   And below would be for 1.3 sources (note when changing
    162   to 1.3 you must also set java_use_vector=true):
    163 
    164       <plugin>
    165         <artifactId>maven-compiler-plugin</artifactId>
    166         <configuration>
    167           <source>1.3</source>
    168           <target>1.5</target>
    169         </configuration>
    170       </plugin>
    171 
    172 java_package=<file-name>|<package-name> (no default)
    173   This allows overriding the 'java_package' option value
    174   for the given file from the command line. Use multiple
    175   java_package options to override the option for multiple
    176   files. The final Java package for each file is the value
    177   of this command line option if present, or the value of
    178   the same option defined in the file if present, or the
    179   proto package if present, or the default Java package.
    180 
    181 java_outer_classname=<file-name>|<outer-classname> (no default)
    182   This allows overriding the 'java_outer_classname' option
    183   for the given file from the command line. Use multiple
    184   java_outer_classname options to override the option for
    185   multiple files. The final Java outer class name for each
    186   file is the value of this command line option if present,
    187   or the value of the same option defined in the file if
    188   present, or the file name converted to CamelCase. This
    189   outer class will nest all classes and integer constants
    190   generated from file-scope messages and enums.
    191 
    192 java_multiple_files={true,false} (no default)
    193   This allows overriding the 'java_multiple_files' option
    194   in all source files and their imported files from the
    195   command line. The final value of this option for each
    196   file is the value defined in this command line option, or
    197   the value of the same option defined in the file if
    198   present, or false. This specifies whether to generate
    199   package-level classes for the file-scope messages in the
    200   same Java package as the outer class (instead of nested
    201   classes in the outer class). File-scope enum constants
    202   are still generated as integer constants in the outer
    203   class. This affects the fully qualified references in the
    204   Java code. NOTE: because the command line option
    205   overrides the value for all files and their imported
    206   files, using this option inconsistently may result in
    207   incorrect references to the imported messages and enum
    208   constants.
    209 
    210 
    211 IMPORTANT: change of javamicro_out behavior:
    212 
    213 In previous versions, if the outer class name has not been
    214 given explicitly, javamicro_out would not infer the outer
    215 class name from the file name, and would skip the outer
    216 class generation. This makes the compilation succeed only
    217 if the source file contains a single message and no enums,
    218 and the generated class for that message is placed at the
    219 package level. To re-align with java_out, javamicro_out
    220 will now always generate the outer class, inferring its
    221 name from the file name if not given, as a container of the
    222 message classes and enum constants. To keep any existing
    223 single-message source file from causing the generation of
    224 an unwanted outer class, you can set the option
    225 java_multiple_files to true, either in the file or as a
    226 command line option.
    227 
    228 
    229 Below are a series of examples for clarification of the
    230 various parameters and options. Assuming this file:
    231 
    232 src/proto/simple-data-protos.proto:
    233 
    234     package testprotobuf;
    235 
    236     message SimpleData {
    237       optional fixed64 id = 1;
    238       optional string description = 2;
    239       optional bool ok = 3 [default = false];
    240     };
    241 
    242 and the compiled protoc in the current working directory,
    243 then a simple command line to compile this file would be:
    244 
    245 ./protoc --javamicro_out=. src/proto/simple-data-protos.proto
    246 
    247 This will create testprotobuf/SimpleDataProtos.java, which
    248 has the following content (extremely simplified):
    249 
    250     package testprotobuf;
    251 
    252     public final class SimpleDataProtos {
    253       public static final class SimpleData
    254           extends MessageMicro {
    255         ...
    256       }
    257     }
    258 
    259 The message SimpleData is compiled into the SimpleData
    260 class, nested in the file's outer class SimpleDataProtos,
    261 whose name is implicitly defined by the proto file name
    262 "simple-data-protos".
    263 
    264 The directory, aka Java package, testprotobuf is created
    265 because on line 1 of simple-data-protos.proto is
    266 "package testprotobuf;". If you wanted a different
    267 package name you could use the java_package option in the
    268 file:
    269 
    270     option java_package = "my_package";
    271 
    272 or in command line sub-parameter:
    273 
    274 ./protoc '--javamicro_out=\
    275 java_package=src/proto/simple-data-protos.proto|my_package:\
    276 .' src/proto/simple-data-protos.proto
    277 
    278 Here you see the new java_package sub-parameter which
    279 itself needs two parameters the file name and the
    280 package name, these are separated by "|". The value set
    281 in the command line overrides the value set in the file.
    282 Now you'll find SimpleDataProtos.java in the my_package/
    283 directory.
    284 
    285 If you wanted to also change the optimization for
    286 speed you'd add opt=speed with the comma seperator
    287 as follows:
    288 
    289 ./protoc '--javamicro_out=\
    290 opt=speed,\
    291 java_package=src/proto/simple-data-protos.proto|my_package:
    292 .' src/proto/simple-data-protos.proto
    293 
    294 If you also wanted a different outer class name you'd
    295 do the following:
    296 
    297 ./protoc '--javamicro_out=\
    298 opt=speed,\
    299 java_package=src/proto/simple-data-protos.proto|my_package,\
    300 java_outer_classname=src/proto/simple-data-protos.proto|OuterName:\
    301 .' src/proto/simple-data-protos.proto
    302 
    303 Now you'll find my_package/OuterName.java and the
    304 message class SimpleData nested in it.
    305 
    306 As mentioned java_package, java_outer_classname and
    307 java_multiple_files may also be specified in the file.
    308 In the example below we must define
    309 java_outer_classname because otherwise the outer class
    310 and one of the message classes will have the same name,
    311 which is forbidden to prevent name ambiguity:
    312 
    313 src/proto/sample-message.proto:
    314 
    315     package testmicroruntime;
    316 
    317     option java_package = "com.example";
    318     option java_outer_classname = "SampleMessageProtos";
    319 
    320     enum MessageType {
    321       SAMPLE = 1;
    322       EXAMPLE = 2;
    323     }
    324 
    325     message SampleMessage {
    326       required int32 id = 1;
    327       required MessageType type = 2;
    328     }
    329 
    330     message SampleMessageContainer {
    331       required SampleMessage message = 1;
    332     }
    333 
    334 This could be compiled using:
    335 
    336 ./protoc --javamicro_out=. src/proto/sample-message.proto
    337 
    338 and the output will be:
    339 
    340 com/example/SampleMessageProtos.java:
    341 
    342     package com.example;
    343 
    344     public final class SampleMessageProtos {
    345       public static final int SAMPLE = 1;
    346       public static final int EXAMPLE = 2;
    347       public static final class SampleMessage
    348           extends MessageMicro {
    349         ...
    350       }
    351       public static final class SampleMessageContainer
    352           extends MessageMicro {
    353         ...
    354       }
    355     }
    356 
    357 As you can see the file-scope enum MessageType is
    358 disassembled into two integer constants in the outer class.
    359 In javamicro_out, all enums are disassembled and compiled
    360 into integer constants in the parent scope (the containing
    361 message's class or the file's (i.e. outer) class).
    362 
    363 You may prefer the file-scope messages to be saved in
    364 separate files. You can do this by setting the option
    365 java_multiple_files to true, in either the file like this:
    366 
    367     option java_multiple_files = true;
    368 
    369 or the command line like this:
    370 
    371 ./protoc --javamicro_out=\
    372 java_multiple_files=true:\
    373 . src/proto/sample-message.proto
    374 
    375 The java_multiple_files option causes javamicro to use a
    376 separate file for each file-scope message, which resides
    377 directly in the Java package alongside the outer class:
    378 
    379 com/example/SampleMessageProtos.java:
    380 
    381     package com.example;
    382     public final class SampleMessageProtos {
    383       public static final int SAMPLE = 1;
    384       public static final int EXAMPLE = 2;
    385     }
    386 
    387 com/example/SampleMessage.java:
    388 
    389     package com.example;
    390     public final class SampleMessage
    391         extends MessageMicro {
    392       ...
    393     }
    394 
    395 com/example/SampleMessageContainer.java:
    396 
    397     package com.example;
    398     public final class SampleMessageContainer
    399         extends MessageMicro {
    400       ...
    401     }
    402 
    403 As you can see, the outer class now contains only the
    404 integer constants, generated from the file-scope enum
    405 "MessageType". Please note that message-scope enums are
    406 still generated as integer constants in the message class.
    407 
    408 
    409 Nano version
    410 ============================
    411 
    412 Nano is a special code generator and runtime library designed specially
    413 for Android, and is very resource-friendly in both the amount of code
    414 and the runtime overhead. An overview of Nano features:
    415 
    416 - No descriptors or message builders.
    417 - All messages are mutable; fields are public Java fields.
    418 - For optional fields only, encapsulation behind setter/getter/hazzer/
    419   clearer functions is opt-in, which provide proper 'has' state support.
    420 - If not opted in, has state is not available. Serialization outputs
    421   all fields not equal to their defaults (see important implications
    422   below).
    423 - Required fields are always serialized.
    424 - Enum constants are integers; protection against invalid values only
    425   when parsing from the wire.
    426 - Enum constants can be generated into container interfaces bearing
    427   the enum's name (so the referencing code is in Java style).
    428 - CodedInputByteBufferNano can only take byte[] (not InputStream).
    429 - Similarly CodedOutputByteBufferNano can only write to byte[].
    430 - Repeated fields are in arrays, not ArrayList or Vector. Null array
    431   elements are allowed and silently ignored.
    432 - Full support of serializing/deserializing repeated packed fields.
    433 - Support of extensions.
    434 - Unset messages/groups are null, not an immutable empty default
    435   instance.
    436 - toByteArray(...) and mergeFrom(...) are now static functions of
    437   MessageNano.
    438 - The 'bytes' type translates to the Java type byte[].
    439 
    440 The generated messages are not thread-safe for writes, but may be
    441 used simultaneously from multiple threads in a read-only manner.
    442 In other words, an appropriate synchronization mechanism (such as
    443 a ReadWriteLock) must be used to ensure that a message, its
    444 ancestors, and descendants are not accessed by any other threads
    445 while the message is being modified. Field reads, getter methods
    446 (but not getExtension(...)), toByteArray(...), writeTo(...),
    447 getCachedSize(), and getSerializedSize() are all considered read-only
    448 operations.
    449 
    450 IMPORTANT: If you have fields with defaults and opt out of accessors
    451 
    452 How fields with defaults are serialized has changed. Because we don't
    453 keep "has" state, any field equal to its default is assumed to be not
    454 set and therefore is not serialized. Consider the situation where we
    455 change the default value of a field. Senders compiled against an older
    456 version of the proto continue to match against the old default, and
    457 don't send values to the receiver even though the receiver assumes the
    458 new default value. Therefore, think carefully about the implications
    459 of changing the default value. Alternatively, turn on accessors and
    460 enjoy the benefit of the explicit has() checks.
    461 
    462 IMPORTANT: If you have "bytes" fields with non-empty defaults
    463 
    464 Because the byte buffer is now of mutable type byte[], the default
    465 static final cannot be exposed through a public field. Each time a
    466 message's constructor or clear() function is called, the default value
    467 (kept in a private byte[]) is cloned. This causes a small memory
    468 penalty. This is not a problem if the field has no default or is an
    469 empty default.
    470 
    471 Nano Generator options
    472 
    473 java_package           -> <file-name>|<package-name>
    474 java_outer_classname   -> <file-name>|<package-name>
    475 java_multiple_files    -> true or false
    476 java_nano_generate_has -> true or false [DEPRECATED]
    477 optional_field_style   -> default or accessors
    478 enum_style             -> c or java
    479 ignore_services        -> true or false
    480 parcelable_messages    -> true or false
    481 
    482 java_package:
    483 java_outer_classname:
    484 java_multiple_files:
    485   Same as Micro version.
    486 
    487 java_nano_generate_has={true,false} (default: false)
    488   DEPRECATED. Use optional_field_style=accessors.
    489 
    490   If true, generates a public boolean variable has<fieldname>
    491   accompanying each optional or required field (not present for
    492   repeated fields, groups or messages). It is set to false initially
    493   and upon clear(). If parseFrom(...) reads the field from the wire,
    494   it is set to true. This is a way for clients to inspect the "has"
    495   value upon parse. If it is set to true, writeTo(...) will ALWAYS
    496   output that field (even if field value is equal to its
    497   default).
    498 
    499   IMPORTANT: This option costs an extra 4 bytes per primitive field in
    500   the message. Think carefully about whether you really need this. In
    501   many cases reading the default works and determining whether the
    502   field was received over the wire is irrelevant.
    503 
    504 optional_field_style={default,accessors,reftypes} (default: default)
    505   Defines the style of the generated code for fields.
    506 
    507   * default *
    508 
    509   In the default style, optional fields translate into public mutable
    510   Java fields, and the serialization process is as discussed in the
    511   "IMPORTANT" section above. 
    512 
    513   * accessors *
    514 
    515   When set to 'accessors', each optional field is encapsulated behind
    516   4 accessors, namely get<fieldname>(), set<fieldname>(), has<fieldname>()
    517   and clear<fieldname>() methods, with the standard semantics. The hazzer's
    518   return value determines whether a field is serialized, so this style is
    519   useful when you need to serialize a field with the default value, or check
    520   if a field has been explicitly set to its default value from the wire.
    521 
    522   In the 'accessors' style, required and nested message fields are still
    523   translated to one public mutable Java field each, repeated fields are still
    524   translated to arrays. No accessors are generated for them.
    525 
    526   IMPORTANT: When using the 'accessors' style, ProGuard should always
    527   be enabled with optimization (don't use -dontoptimize) and allowing
    528   access modification (use -allowaccessmodification). This removes the
    529   unused accessors and maybe inline the rest at the call sites,
    530   reducing the final code size.
    531   TODO(maxtroy): find ProGuard config that would work the best.
    532 
    533   * reftypes *
    534 
    535   When set to 'reftypes', each proto field is generated as a public Java
    536   field. For primitive types, these fields use the Java reference types
    537   such as java.lang.Integer instead of primitive types such as int.
    538 
    539   In the 'reftypes' style, fields are initialized to null (or empty
    540   arrays for repeated fields), and their default values are not available.
    541   They are serialized over the wire based on equality to null.
    542 
    543   The 'reftypes' mode has some additional cost due to autoboxing and usage
    544   of reference types. In practice, many boxed types are cached, and so don't
    545   result in object creation. However, references do take slightly more memory
    546   than primitives.
    547 
    548   The 'reftypes' mode is useful when you want to be able to serialize fields
    549   with default values, or check if a field has been explicitly set to the
    550   default over the wire without paying the extra method cost of the
    551   'accessors' mode.
    552 
    553   Note that if you attempt to write null to a required field in the reftypes
    554   mode, serialization of the proto will cause a NullPointerException. This is
    555   an intentional indicator that you must set required fields.
    556 
    557   NOTE
    558   optional_field_style=accessors or reftypes cannot be used together with
    559   java_nano_generate_has=true. If you need the 'has' flag for any
    560   required field (you have no reason to), you can only use
    561   java_nano_generate_has=true.
    562 
    563 enum_style={c,java} (default: c)
    564   Defines where to put the int constants generated from enum members.
    565 
    566   * c *
    567 
    568   Use C-style, so the enum constants are available at the scope where
    569   the enum is defined. A file-scope enum's members are referenced like
    570   'FileOuterClass.ENUM_VALUE'; a message-scope enum's members are
    571   referenced as 'Message.ENUM_VALUE'. The enum name is unavailable.
    572   This complies with the Micro code generator's behavior.
    573 
    574   * java *
    575 
    576   Use Java-style, so the enum constants are available under the enum
    577   name and referenced like 'EnumName.ENUM_VALUE' (they are still int
    578   constants). The enum name becomes the name of a public interface, at
    579   the scope where the enum is defined. If the enum is file-scope and
    580   the java_multiple_files option is on, the interface will be defined
    581   in its own file. To reduce code size, this interface should not be
    582   implemented and ProGuard shrinking should be used, so after the Java
    583   compiler inlines all referenced enum constants into the call sites,
    584   the interface remains unused and can be removed by ProGuard.
    585 
    586 ignore_services={true,false} (default: false)
    587   Skips services definitions.
    588 
    589   Nano doesn't support services. By default, if a service is defined
    590   it will generate a compilation error. If this flag is set to true,
    591   services will be silently ignored, instead.
    592 
    593 parcelable_messages={true,false} (default: false)
    594   Android-specific option to generate Parcelable messages.
    595 
    596 
    597 To use nano protobufs within the Android repo:
    598 
    599 - Set 'LOCAL_PROTOC_OPTIMIZE_TYPE := nano' in your local .mk file.
    600   When building a Java library or an app (package) target, the build
    601   system will add the Java nano runtime library to the
    602   LOCAL_STATIC_JAVA_LIBRARIES variable, so you don't need to.
    603 - Set 'LOCAL_PROTO_JAVA_OUTPUT_PARAMS := ...' in your local .mk file
    604   for any command-line options you need. Use commas to join multiple
    605   options. In the nano flavor only, whitespace surrounding the option
    606   names and values are ignored, so you can use backslash-newline or
    607   '+=' to structure your make files nicely.
    608 - The options will be applied to *all* proto files in LOCAL_SRC_FILES
    609   when you build a Java library or package. In case different options
    610   are needed for different proto files, build separate Java libraries
    611   and reference them in your main target. Note: you should make sure
    612   that, for each separate target, all proto files imported from any
    613   proto file in LOCAL_SRC_FILES are included in LOCAL_SRC_FILES. This
    614   is because the generator has to assume that the imported files are
    615   built using the same options, and will generate code that reference
    616   the fields and enums from the imported files using the same code
    617   style.
    618 - Hint: 'include $(CLEAR_VARS)' resets all LOCAL_ variables, including
    619   the two above.
    620 
    621 To use nano protobufs outside of Android repo:
    622 
    623 - Link with the generated jar file
    624   <protobuf-root>java/target/protobuf-java-2.3.0-nano.jar.
    625 - Invoke with --javanano_out, e.g.:
    626 
    627 ./protoc '--javanano_out=\
    628     java_package=src/proto/simple-data.proto|my_package,\
    629     java_outer_classname=src/proto/simple-data.proto|OuterName\
    630   :.' src/proto/simple-data.proto
    631 
    632 Contributing to nano:
    633 
    634 Please add/edit tests in NanoTest.java.
    635 
    636 Please run the following steps to test:
    637 
    638 - cd external/protobuf
    639 - ./configure
    640 - Run "make -j12 check" and verify all tests pass.
    641 - cd java
    642 - Run "mvn test" and verify all tests pass.
    643 - cd ../../..
    644 - . build/envsetup.sh
    645 - lunch 1
    646 - "make -j12 aprotoc libprotobuf-java-2.3.0-nano aprotoc-test-nano-params NanoAndroidTest" and
    647   check for build errors.
    648 - Plug in an Android device or start an emulator.
    649 - adb install -r out/target/product/generic/data/app/NanoAndroidTest.apk
    650 - Run:
    651   "adb shell am instrument -w com.google.protobuf.nano.test/android.test.InstrumentationTestRunner"
    652   and verify all tests pass.
    653 - repo sync -c -j256
    654 - "make -j12" and check for build errors
    655 
    656 
    657 Usage
    658 =====
    659 
    660 The complete documentation for Protocol Buffers is available via the
    661 web at:
    662 
    663   http://code.google.com/apis/protocolbuffers/
    664