content: // Protocol Buffers - Google's data interchange format
  // Copyright 2008 Google Inc.  All rights reserved.
  // https://developers.google.com/protocol-buffers/
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  //     * Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  //     * Redistributions in binary form must reproduce the above
  // copyright notice, this list of conditions and the following disclaimer
  // in the documentation and/or other materials provided with the
  // distribution.
  //     * Neither the name of Google Inc. nor the names of its
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  package com.google.protobuf;
  
  /**
   * RawMessageInfo stores the same amount of information as {@link MessageInfo} but in a more compact
   * format.
   */
  final class RawMessageInfo implements MessageInfo {
  
    private final MessageLite defaultInstance;
  
    /**
     * The compact format packs everything in a String object and a Object[] array. The String object
     * is encoded with field number, field type, hasbits offset, oneof index, etc., whereas the
     * Object[] array contains field references, class references, instance references, etc.
     *
     * <p>The String object encodes a sequence of integers into UTF-16 characters. For each int, it
     * will be encoding into 1 to 3 UTF-16 characters depending on its unsigned value:
     *
     * <ul>
     *   <li>1 char: [c1: 0x0000 - 0xD7FF] = int of the same value.
     *   <li>2 chars: [c1: 0xE000 - 0xFFFF], [c2: 0x0000 - 0xD7FF] = (c2 << 13) | (c1 & 0x1FFF)
     *   <li>3 chars: [c1: 0xE000 - 0xFFFF], [c2: 0xE000 - 0xFFFF], [c3: 0x0000 - 0xD7FF] = (c3 << 26)
     *       | ((c2 & 0x1FFF) << 13) | (c1 & 0x1FFF)
     * </ul>
     *
     * <p>Note that we don't use UTF-16 surrogate pairs [0xD800 - 0xDFFF] because they have to come in
     * pairs to form a valid UTF-16char sequence and don't help us encode values more efficiently.
     *
     * <p>The integer sequence encoded in the String object has the following layout:
     *
     * <ul>
     *   <li>[0]: flags, flags & 0x1 = is proto2?, flags & 0x2 = is message?.
     *   <li>[1]: field count, if 0, this is the end of the integer sequence and the corresponding
     *       Object[] array should be null.
     *   <li>[2]: oneof count
     *   <li>[3]: hasbits count, how many hasbits integers are generated.
     *   <li>[4]: min field number
     *   <li>[5]: max field number
     *   <li>[6]: total number of entries need to allocate
     *   <li>[7]: map field count
     *   <li>[8]: repeated field count, this doesn't include map fields.
     *   <li>[9]: size of checkInitialized array
     *   <li>[...]: field entries
     * </ul>
     *
     * <p>Each field entry starts with a field number and the field type:
     *
     * <ul>
     *   <li>[0]: field number
     *   <li>[1]: field type with extra bits:
     *       <ul>
     *         <li>v & 0xFF = field type as defined in the FieldType class
     *         <li>v & 0x100 = is required?
     *         <li>v & 0x200 = is checkUtf8?
     *         <li>v & 0x400 = needs isInitialized check?
     *         <li>v & 0x800 = is map field with proto2 enum value?
     *       </ul>
     * </ul>
     *
     * If the file is proto2 and this is a singular field:
     *
     * <ul>
     *   <li>[2]: hasbits offset
     * </ul>
     *
     * If the field is in an oneof:
     *
     * <ul>
     *   <li>[2]: oenof index
     * </ul>
     *
     * For other types, the field entry only has field number and field type.
     *
     * <p>The Object[] array has 3 sections:
     *
     * <ul>
     *   <li>---- oneof section ----
     *       <ul>
     *         <li>[0]: value field for oneof 1.
     *         <li>[1]: case field for oneof 1.
     *         <li>...
     *         <li>[.]: value field for oneof n.
     *         <li>[.]: case field for oneof n.
     *       </ul>
     *   <li>---- hasbits section ----
     *       <ul>
     *         <li>[.]: hasbits field 1
     *         <li>[.]: hasbits field 2
     *         <li>...
     *         <li>[.]: hasbits field n
     *       </ul>
     *   <li>---- field section ----
     *       <ul>
     *         <li>[...]: field entries
     *       </ul>
     * </ul>
     *
     * <p>In the Object[] array, field entries are ordered in the same way as field entries in the
     * String object. The size of each entry is determined by the field type.
     *
     * <ul>
     *   <li>Oneof field:
     *       <ul>
     *         <li>Oneof message field:
     *             <ul>
     *               <li>[0]: message class reference.
     *             </ul>
     *         <li>Oneof enum fieldin proto2:
     *             <ul>
     *               <li>[0]: EnumLiteMap
     *             </ul>
     *         <li>For all other oneof fields, field entry in the Object[] array is empty.
     *       </ul>
     *   <li>Repeated message field:
     *       <ul>
     *         <li>[0]: field reference
     *         <li>[1]: message class reference
     *       </ul>
     *   <li>Proto2 singular/repeated enum field:
     *       <ul>
     *         <li>[0]: field reference
     *         <li>[1]: EnumLiteMap
     *       </ul>
     *   <li>Map field with a proto2 enum value:
     *       <ul>
     *         <li>[0]: field reference
     *         <li>[1]: map default entry instance
     *         <li>[2]: EnumLiteMap
     *       </ul>
     *   <li>Map field with other value types:
     *       <ul>
     *         <li>[0]: field reference
     *         <li>[1]: map default entry instance
     *       </ul>
     *   <li>All other field type:
     *       <ul>
     *         <li>[0]: field reference
     *       </ul>
     * </ul>
     *
     * <p>In order to read the field info from this compact format, a reader needs to progress through
     * the String object and the Object[] array simultaneously.
     */
    private final String info;
  
    private final Object[] objects;
    private final int flags;
  
    RawMessageInfo(MessageLite defaultInstance, String info, Object[] objects) {
      this.defaultInstance = defaultInstance;
      this.info = info;
      this.objects = objects;
      int position = 0;
      int value = (int) info.charAt(position++);
      if (value < 0xD800) {
        flags = value;
      } else {
        int result = value & 0x1FFF;
        int shift = 13;
        while ((value = info.charAt(position++)) >= 0xD800) {
          result |= (value & 0x1FFF) << shift;
          shift += 13;
        }
        flags = result | (value << shift);
      }
    }
  
    String getStringInfo() {
      return info;
    }
  
    Object[] getObjects() {
      return objects;
    }
  
    @Override
    public MessageLite getDefaultInstance() {
      return defaultInstance;
    }
  
    @Override
    public ProtoSyntax getSyntax() {
      return (flags & 0x1) == 0x1 ? ProtoSyntax.PROTO2 : ProtoSyntax.PROTO3;
    }
  
    @Override
    public boolean isMessageSetWireFormat() {
      return (flags & 0x2) == 0x2;
    }
  }
  