// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: js/js.serializer/src/js-ast.debug.proto

package org.jetbrains.kotlin.serialization.js.ast;

public final class DebugJsAstProtoBuf {
  private DebugJsAstProtoBuf() {}
  public static void registerAllExtensions(
      org.jetbrains.kotlin.protobuf.ExtensionRegistry registry) {
  }
  /**
   * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.ast.SideEffects}
   */
  public enum SideEffects
      implements org.jetbrains.kotlin.protobuf.ProtocolMessageEnum {
    /**
     * <code>AFFECTS_STATE = 1;</code>
     */
    AFFECTS_STATE(0, 1),
    /**
     * <code>DEPENDS_ON_STATE = 2;</code>
     */
    DEPENDS_ON_STATE(1, 2),
    /**
     * <code>PURE = 3;</code>
     */
    PURE(2, 3),
    ;

    /**
     * <code>AFFECTS_STATE = 1;</code>
     */
    public static final int AFFECTS_STATE_VALUE = 1;
    /**
     * <code>DEPENDS_ON_STATE = 2;</code>
     */
    public static final int DEPENDS_ON_STATE_VALUE = 2;
    /**
     * <code>PURE = 3;</code>
     */
    public static final int PURE_VALUE = 3;


    public final int getNumber() { return value; }

    public static SideEffects valueOf(int value) {
      switch (value) {
        case 1: return AFFECTS_STATE;
        case 2: return DEPENDS_ON_STATE;
        case 3: return PURE;
        default: return null;
      }
    }

    public static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<SideEffects>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<SideEffects>
        internalValueMap =
          new org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<SideEffects>() {
            public SideEffects findValueByNumber(int number) {
              return SideEffects.valueOf(number);
            }
          };

    public final org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(index);
    }
    public final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.getDescriptor().getEnumTypes().get(0);
    }

    private static final SideEffects[] VALUES = values();

    public static SideEffects valueOf(
        org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int index;
    private final int value;

    private SideEffects(int index, int value) {
      this.index = index;
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.ast.SideEffects)
  }

  /**
   * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.ast.InlineStrategy}
   */
  public enum InlineStrategy
      implements org.jetbrains.kotlin.protobuf.ProtocolMessageEnum {
    /**
     * <code>AS_FUNCTION = 0;</code>
     */
    AS_FUNCTION(0, 0),
    /**
     * <code>IN_PLACE = 1;</code>
     */
    IN_PLACE(1, 1),
    /**
     * <code>NOT_INLINE = 2;</code>
     */
    NOT_INLINE(2, 2),
    ;

    /**
     * <code>AS_FUNCTION = 0;</code>
     */
    public static final int AS_FUNCTION_VALUE = 0;
    /**
     * <code>IN_PLACE = 1;</code>
     */
    public static final int IN_PLACE_VALUE = 1;
    /**
     * <code>NOT_INLINE = 2;</code>
     */
    public static final int NOT_INLINE_VALUE = 2;


    public final int getNumber() { return value; }

    public static InlineStrategy valueOf(int value) {
      switch (value) {
        case 0: return AS_FUNCTION;
        case 1: return IN_PLACE;
        case 2: return NOT_INLINE;
        default: return null;
      }
    }

    public static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<InlineStrategy>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<InlineStrategy>
        internalValueMap =
          new org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<InlineStrategy>() {
            public InlineStrategy findValueByNumber(int number) {
              return InlineStrategy.valueOf(number);
            }
          };

    public final org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(index);
    }
    public final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.getDescriptor().getEnumTypes().get(1);
    }

    private static final InlineStrategy[] VALUES = values();

    public static InlineStrategy valueOf(
        org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int index;
    private final int value;

    private InlineStrategy(int index, int value) {
      this.index = index;
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.ast.InlineStrategy)
  }

  /**
   * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.ast.SpecialFunction}
   */
  public enum SpecialFunction
      implements org.jetbrains.kotlin.protobuf.ProtocolMessageEnum {
    /**
     * <code>DEFINE_INLINE_FUNCTION = 1;</code>
     */
    DEFINE_INLINE_FUNCTION(0, 1),
    /**
     * <code>WRAP_FUNCTION = 2;</code>
     */
    WRAP_FUNCTION(1, 2),
    /**
     * <code>TO_BOXED_CHAR = 3;</code>
     */
    TO_BOXED_CHAR(2, 3),
    /**
     * <code>UNBOX_CHAR = 4;</code>
     */
    UNBOX_CHAR(3, 4),
    /**
     * <code>SUSPEND_CALL = 5;</code>
     */
    SUSPEND_CALL(4, 5),
    /**
     * <code>COROUTINE_RESULT = 6;</code>
     */
    COROUTINE_RESULT(5, 6),
    /**
     * <code>COROUTINE_CONTROLLER = 7;</code>
     */
    COROUTINE_CONTROLLER(6, 7),
    /**
     * <code>COROUTINE_RECEIVER = 8;</code>
     */
    COROUTINE_RECEIVER(7, 8),
    /**
     * <code>SET_COROUTINE_RESULT = 9;</code>
     */
    SET_COROUTINE_RESULT(8, 9),
    ;

    /**
     * <code>DEFINE_INLINE_FUNCTION = 1;</code>
     */
    public static final int DEFINE_INLINE_FUNCTION_VALUE = 1;
    /**
     * <code>WRAP_FUNCTION = 2;</code>
     */
    public static final int WRAP_FUNCTION_VALUE = 2;
    /**
     * <code>TO_BOXED_CHAR = 3;</code>
     */
    public static final int TO_BOXED_CHAR_VALUE = 3;
    /**
     * <code>UNBOX_CHAR = 4;</code>
     */
    public static final int UNBOX_CHAR_VALUE = 4;
    /**
     * <code>SUSPEND_CALL = 5;</code>
     */
    public static final int SUSPEND_CALL_VALUE = 5;
    /**
     * <code>COROUTINE_RESULT = 6;</code>
     */
    public static final int COROUTINE_RESULT_VALUE = 6;
    /**
     * <code>COROUTINE_CONTROLLER = 7;</code>
     */
    public static final int COROUTINE_CONTROLLER_VALUE = 7;
    /**
     * <code>COROUTINE_RECEIVER = 8;</code>
     */
    public static final int COROUTINE_RECEIVER_VALUE = 8;
    /**
     * <code>SET_COROUTINE_RESULT = 9;</code>
     */
    public static final int SET_COROUTINE_RESULT_VALUE = 9;


    public final int getNumber() { return value; }

    public static SpecialFunction valueOf(int value) {
      switch (value) {
        case 1: return DEFINE_INLINE_FUNCTION;
        case 2: return WRAP_FUNCTION;
        case 3: return TO_BOXED_CHAR;
        case 4: return UNBOX_CHAR;
        case 5: return SUSPEND_CALL;
        case 6: return COROUTINE_RESULT;
        case 7: return COROUTINE_CONTROLLER;
        case 8: return COROUTINE_RECEIVER;
        case 9: return SET_COROUTINE_RESULT;
        default: return null;
      }
    }

    public static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<SpecialFunction>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<SpecialFunction>
        internalValueMap =
          new org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<SpecialFunction>() {
            public SpecialFunction findValueByNumber(int number) {
              return SpecialFunction.valueOf(number);
            }
          };

    public final org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(index);
    }
    public final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.getDescriptor().getEnumTypes().get(2);
    }

    private static final SpecialFunction[] VALUES = values();

    public static SpecialFunction valueOf(
        org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int index;
    private final int value;

    private SpecialFunction(int index, int value) {
      this.index = index;
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.ast.SpecialFunction)
  }

  public interface LocationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Location)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 startLine = 1;</code>
     */
    boolean hasStartLine();
    /**
     * <code>required int32 startLine = 1;</code>
     */
    int getStartLine();

    /**
     * <code>required int32 startChar = 2;</code>
     */
    boolean hasStartChar();
    /**
     * <code>required int32 startChar = 2;</code>
     */
    int getStartChar();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Location}
   */
  public static final class Location extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Location)
      LocationOrBuilder {
    // Use Location.newBuilder() to construct.
    private Location(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Location(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Location defaultInstance;
    public static Location getDefaultInstance() {
      return defaultInstance;
    }

    public Location getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Location(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              startLine_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              startChar_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Location> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Location>() {
      public Location parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Location(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Location> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int STARTLINE_FIELD_NUMBER = 1;
    private int startLine_;
    /**
     * <code>required int32 startLine = 1;</code>
     */
    public boolean hasStartLine() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 startLine = 1;</code>
     */
    public int getStartLine() {
      return startLine_;
    }

    public static final int STARTCHAR_FIELD_NUMBER = 2;
    private int startChar_;
    /**
     * <code>required int32 startChar = 2;</code>
     */
    public boolean hasStartChar() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 startChar = 2;</code>
     */
    public int getStartChar() {
      return startChar_;
    }

    private void initFields() {
      startLine_ = 0;
      startChar_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasStartLine()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStartChar()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, startLine_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, startChar_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, startLine_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, startChar_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Location}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Location)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        startLine_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        startChar_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.startLine_ = startLine_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startChar_ = startChar_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance()) return this;
        if (other.hasStartLine()) {
          setStartLine(other.getStartLine());
        }
        if (other.hasStartChar()) {
          setStartChar(other.getStartChar());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasStartLine()) {
          
          return false;
        }
        if (!hasStartChar()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int startLine_ ;
      /**
       * <code>required int32 startLine = 1;</code>
       */
      public boolean hasStartLine() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 startLine = 1;</code>
       */
      public int getStartLine() {
        return startLine_;
      }
      /**
       * <code>required int32 startLine = 1;</code>
       */
      public Builder setStartLine(int value) {
        bitField0_ |= 0x00000001;
        startLine_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 startLine = 1;</code>
       */
      public Builder clearStartLine() {
        bitField0_ = (bitField0_ & ~0x00000001);
        startLine_ = 0;
        onChanged();
        return this;
      }

      private int startChar_ ;
      /**
       * <code>required int32 startChar = 2;</code>
       */
      public boolean hasStartChar() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int32 startChar = 2;</code>
       */
      public int getStartChar() {
        return startChar_;
      }
      /**
       * <code>required int32 startChar = 2;</code>
       */
      public Builder setStartChar(int value) {
        bitField0_ |= 0x00000002;
        startChar_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 startChar = 2;</code>
       */
      public Builder clearStartChar() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startChar_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Location)
    }

    static {
      defaultInstance = new Location(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Location)
  }

  public interface ExpressionOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Expression)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 fileId = 1;</code>
     */
    boolean hasFileId();
    /**
     * <code>optional int32 fileId = 1;</code>
     */
    int getFileId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    boolean hasLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder();

    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    boolean hasSynthetic();
    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    boolean getSynthetic();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
     */
    boolean hasSideEffects();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects getSideEffects();

    /**
     * <code>optional int32 local_alias = 5;</code>
     */
    boolean hasLocalAlias();
    /**
     * <code>optional int32 local_alias = 5;</code>
     */
    int getLocalAlias();

    /**
     * <code>optional int32 simple_name_reference = 22;</code>
     */
    boolean hasSimpleNameReference();
    /**
     * <code>optional int32 simple_name_reference = 22;</code>
     */
    int getSimpleNameReference();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
     */
    boolean hasThisLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral getThisLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder getThisLiteralOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
     */
    boolean hasNullLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral getNullLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder getNullLiteralOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
     */
    boolean hasTrueLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral getTrueLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder getTrueLiteralOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
     */
    boolean hasFalseLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral getFalseLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder getFalseLiteralOrBuilder();

    /**
     * <code>optional int32 string_literal = 27;</code>
     */
    boolean hasStringLiteral();
    /**
     * <code>optional int32 string_literal = 27;</code>
     */
    int getStringLiteral();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
     */
    boolean hasRegExpLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral getRegExpLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder getRegExpLiteralOrBuilder();

    /**
     * <code>optional int32 int_literal = 29;</code>
     */
    boolean hasIntLiteral();
    /**
     * <code>optional int32 int_literal = 29;</code>
     */
    int getIntLiteral();

    /**
     * <code>optional double double_literal = 30;</code>
     */
    boolean hasDoubleLiteral();
    /**
     * <code>optional double double_literal = 30;</code>
     */
    double getDoubleLiteral();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
     */
    boolean hasArrayLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral getArrayLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder getArrayLiteralOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
     */
    boolean hasObjectLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral getObjectLiteral();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder getObjectLiteralOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
     */
    boolean hasFunction();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function getFunction();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder getFunctionOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
     */
    boolean hasDocComment();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment getDocComment();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder getDocCommentOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
     */
    boolean hasBinary();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation getBinary();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder getBinaryOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
     */
    boolean hasUnary();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation getUnary();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder getUnaryOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
     */
    boolean hasConditional();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional getConditional();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder getConditionalOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
     */
    boolean hasArrayAccess();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess getArrayAccess();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder getArrayAccessOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
     */
    boolean hasNameReference();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference getNameReference();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder getNameReferenceOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
     */
    boolean hasPropertyReference();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference getPropertyReference();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder getPropertyReferenceOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
     */
    boolean hasInvocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation getInvocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder getInvocationOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
     */
    boolean hasInstantiation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation getInstantiation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder getInstantiationOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Expression}
   */
  public static final class Expression extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Expression)
      ExpressionOrBuilder {
    // Use Expression.newBuilder() to construct.
    private Expression(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Expression(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Expression defaultInstance;
    public static Expression getDefaultInstance() {
      return defaultInstance;
    }

    public Expression getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Expression(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              fileId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = location_.toBuilder();
              }
              location_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(location_);
                location_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              synthetic_ = input.readBool();
              break;
            }
            case 32: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(4, rawValue);
              } else {
                bitField0_ |= 0x00000008;
                sideEffects_ = value;
              }
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              localAlias_ = input.readInt32();
              break;
            }
            case 176: {
              expressionCase_ = 22;
              expression_ = input.readInt32();
              break;
            }
            case 186: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder subBuilder = null;
              if (expressionCase_ == 23) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 23;
              break;
            }
            case 194: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder subBuilder = null;
              if (expressionCase_ == 24) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 24;
              break;
            }
            case 202: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder subBuilder = null;
              if (expressionCase_ == 25) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 25;
              break;
            }
            case 210: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder subBuilder = null;
              if (expressionCase_ == 26) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 26;
              break;
            }
            case 216: {
              expressionCase_ = 27;
              expression_ = input.readInt32();
              break;
            }
            case 226: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder subBuilder = null;
              if (expressionCase_ == 28) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 28;
              break;
            }
            case 232: {
              expressionCase_ = 29;
              expression_ = input.readInt32();
              break;
            }
            case 241: {
              expressionCase_ = 30;
              expression_ = input.readDouble();
              break;
            }
            case 250: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder subBuilder = null;
              if (expressionCase_ == 31) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 31;
              break;
            }
            case 258: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder subBuilder = null;
              if (expressionCase_ == 32) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 32;
              break;
            }
            case 266: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder subBuilder = null;
              if (expressionCase_ == 33) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 33;
              break;
            }
            case 274: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder subBuilder = null;
              if (expressionCase_ == 34) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 34;
              break;
            }
            case 282: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder subBuilder = null;
              if (expressionCase_ == 35) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 35;
              break;
            }
            case 290: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder subBuilder = null;
              if (expressionCase_ == 36) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 36;
              break;
            }
            case 298: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder subBuilder = null;
              if (expressionCase_ == 37) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 37;
              break;
            }
            case 306: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder subBuilder = null;
              if (expressionCase_ == 38) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 38;
              break;
            }
            case 314: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder subBuilder = null;
              if (expressionCase_ == 39) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 39;
              break;
            }
            case 322: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder subBuilder = null;
              if (expressionCase_ == 40) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 40;
              break;
            }
            case 330: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder subBuilder = null;
              if (expressionCase_ == 41) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 41;
              break;
            }
            case 338: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder subBuilder = null;
              if (expressionCase_ == 42) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_).toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_);
                expression_ = subBuilder.buildPartial();
              }
              expressionCase_ = 42;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Expression> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Expression>() {
      public Expression parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Expression(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Expression> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    private int expressionCase_ = 0;
    private java.lang.Object expression_;
    public enum ExpressionCase
        implements org.jetbrains.kotlin.protobuf.Internal.EnumLite {
      SIMPLE_NAME_REFERENCE(22),
      THIS_LITERAL(23),
      NULL_LITERAL(24),
      TRUE_LITERAL(25),
      FALSE_LITERAL(26),
      STRING_LITERAL(27),
      REG_EXP_LITERAL(28),
      INT_LITERAL(29),
      DOUBLE_LITERAL(30),
      ARRAY_LITERAL(31),
      OBJECT_LITERAL(32),
      FUNCTION(33),
      DOC_COMMENT(34),
      BINARY(35),
      UNARY(36),
      CONDITIONAL(37),
      ARRAY_ACCESS(38),
      NAME_REFERENCE(39),
      PROPERTY_REFERENCE(40),
      INVOCATION(41),
      INSTANTIATION(42),
      EXPRESSION_NOT_SET(0);
      private int value = 0;
      private ExpressionCase(int value) {
        this.value = value;
      }
      public static ExpressionCase valueOf(int value) {
        switch (value) {
          case 22: return SIMPLE_NAME_REFERENCE;
          case 23: return THIS_LITERAL;
          case 24: return NULL_LITERAL;
          case 25: return TRUE_LITERAL;
          case 26: return FALSE_LITERAL;
          case 27: return STRING_LITERAL;
          case 28: return REG_EXP_LITERAL;
          case 29: return INT_LITERAL;
          case 30: return DOUBLE_LITERAL;
          case 31: return ARRAY_LITERAL;
          case 32: return OBJECT_LITERAL;
          case 33: return FUNCTION;
          case 34: return DOC_COMMENT;
          case 35: return BINARY;
          case 36: return UNARY;
          case 37: return CONDITIONAL;
          case 38: return ARRAY_ACCESS;
          case 39: return NAME_REFERENCE;
          case 40: return PROPERTY_REFERENCE;
          case 41: return INVOCATION;
          case 42: return INSTANTIATION;
          case 0: return EXPRESSION_NOT_SET;
          default: throw new java.lang.IllegalArgumentException(
            "Value is undefined for this oneof enum.");
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public ExpressionCase
    getExpressionCase() {
      return ExpressionCase.valueOf(
          expressionCase_);
    }

    public static final int FILEID_FIELD_NUMBER = 1;
    private int fileId_;
    /**
     * <code>optional int32 fileId = 1;</code>
     */
    public boolean hasFileId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 fileId = 1;</code>
     */
    public int getFileId() {
      return fileId_;
    }

    public static final int LOCATION_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    public boolean hasLocation() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
      return location_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
      return location_;
    }

    public static final int SYNTHETIC_FIELD_NUMBER = 3;
    private boolean synthetic_;
    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    public boolean hasSynthetic() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    public boolean getSynthetic() {
      return synthetic_;
    }

    public static final int SIDE_EFFECTS_FIELD_NUMBER = 4;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects sideEffects_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
     */
    public boolean hasSideEffects() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects getSideEffects() {
      return sideEffects_;
    }

    public static final int LOCAL_ALIAS_FIELD_NUMBER = 5;
    private int localAlias_;
    /**
     * <code>optional int32 local_alias = 5;</code>
     */
    public boolean hasLocalAlias() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional int32 local_alias = 5;</code>
     */
    public int getLocalAlias() {
      return localAlias_;
    }

    public static final int SIMPLE_NAME_REFERENCE_FIELD_NUMBER = 22;
    /**
     * <code>optional int32 simple_name_reference = 22;</code>
     */
    public boolean hasSimpleNameReference() {
      return expressionCase_ == 22;
    }
    /**
     * <code>optional int32 simple_name_reference = 22;</code>
     */
    public int getSimpleNameReference() {
      if (expressionCase_ == 22) {
        return (java.lang.Integer) expression_;
      }
      return 0;
    }

    public static final int THIS_LITERAL_FIELD_NUMBER = 23;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
     */
    public boolean hasThisLiteral() {
      return expressionCase_ == 23;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral getThisLiteral() {
      if (expressionCase_ == 23) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder getThisLiteralOrBuilder() {
      if (expressionCase_ == 23) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
    }

    public static final int NULL_LITERAL_FIELD_NUMBER = 24;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
     */
    public boolean hasNullLiteral() {
      return expressionCase_ == 24;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral getNullLiteral() {
      if (expressionCase_ == 24) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder getNullLiteralOrBuilder() {
      if (expressionCase_ == 24) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
    }

    public static final int TRUE_LITERAL_FIELD_NUMBER = 25;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
     */
    public boolean hasTrueLiteral() {
      return expressionCase_ == 25;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral getTrueLiteral() {
      if (expressionCase_ == 25) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder getTrueLiteralOrBuilder() {
      if (expressionCase_ == 25) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
    }

    public static final int FALSE_LITERAL_FIELD_NUMBER = 26;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
     */
    public boolean hasFalseLiteral() {
      return expressionCase_ == 26;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral getFalseLiteral() {
      if (expressionCase_ == 26) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder getFalseLiteralOrBuilder() {
      if (expressionCase_ == 26) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
    }

    public static final int STRING_LITERAL_FIELD_NUMBER = 27;
    /**
     * <code>optional int32 string_literal = 27;</code>
     */
    public boolean hasStringLiteral() {
      return expressionCase_ == 27;
    }
    /**
     * <code>optional int32 string_literal = 27;</code>
     */
    public int getStringLiteral() {
      if (expressionCase_ == 27) {
        return (java.lang.Integer) expression_;
      }
      return 0;
    }

    public static final int REG_EXP_LITERAL_FIELD_NUMBER = 28;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
     */
    public boolean hasRegExpLiteral() {
      return expressionCase_ == 28;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral getRegExpLiteral() {
      if (expressionCase_ == 28) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder getRegExpLiteralOrBuilder() {
      if (expressionCase_ == 28) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
    }

    public static final int INT_LITERAL_FIELD_NUMBER = 29;
    /**
     * <code>optional int32 int_literal = 29;</code>
     */
    public boolean hasIntLiteral() {
      return expressionCase_ == 29;
    }
    /**
     * <code>optional int32 int_literal = 29;</code>
     */
    public int getIntLiteral() {
      if (expressionCase_ == 29) {
        return (java.lang.Integer) expression_;
      }
      return 0;
    }

    public static final int DOUBLE_LITERAL_FIELD_NUMBER = 30;
    /**
     * <code>optional double double_literal = 30;</code>
     */
    public boolean hasDoubleLiteral() {
      return expressionCase_ == 30;
    }
    /**
     * <code>optional double double_literal = 30;</code>
     */
    public double getDoubleLiteral() {
      if (expressionCase_ == 30) {
        return (java.lang.Double) expression_;
      }
      return 0D;
    }

    public static final int ARRAY_LITERAL_FIELD_NUMBER = 31;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
     */
    public boolean hasArrayLiteral() {
      return expressionCase_ == 31;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral getArrayLiteral() {
      if (expressionCase_ == 31) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder getArrayLiteralOrBuilder() {
      if (expressionCase_ == 31) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
    }

    public static final int OBJECT_LITERAL_FIELD_NUMBER = 32;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
     */
    public boolean hasObjectLiteral() {
      return expressionCase_ == 32;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral getObjectLiteral() {
      if (expressionCase_ == 32) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder getObjectLiteralOrBuilder() {
      if (expressionCase_ == 32) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
    }

    public static final int FUNCTION_FIELD_NUMBER = 33;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
     */
    public boolean hasFunction() {
      return expressionCase_ == 33;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function getFunction() {
      if (expressionCase_ == 33) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder getFunctionOrBuilder() {
      if (expressionCase_ == 33) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
    }

    public static final int DOC_COMMENT_FIELD_NUMBER = 34;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
     */
    public boolean hasDocComment() {
      return expressionCase_ == 34;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment getDocComment() {
      if (expressionCase_ == 34) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder getDocCommentOrBuilder() {
      if (expressionCase_ == 34) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
    }

    public static final int BINARY_FIELD_NUMBER = 35;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
     */
    public boolean hasBinary() {
      return expressionCase_ == 35;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation getBinary() {
      if (expressionCase_ == 35) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder getBinaryOrBuilder() {
      if (expressionCase_ == 35) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
    }

    public static final int UNARY_FIELD_NUMBER = 36;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
     */
    public boolean hasUnary() {
      return expressionCase_ == 36;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation getUnary() {
      if (expressionCase_ == 36) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder getUnaryOrBuilder() {
      if (expressionCase_ == 36) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
    }

    public static final int CONDITIONAL_FIELD_NUMBER = 37;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
     */
    public boolean hasConditional() {
      return expressionCase_ == 37;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional getConditional() {
      if (expressionCase_ == 37) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder getConditionalOrBuilder() {
      if (expressionCase_ == 37) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
    }

    public static final int ARRAY_ACCESS_FIELD_NUMBER = 38;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
     */
    public boolean hasArrayAccess() {
      return expressionCase_ == 38;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess getArrayAccess() {
      if (expressionCase_ == 38) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder getArrayAccessOrBuilder() {
      if (expressionCase_ == 38) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
    }

    public static final int NAME_REFERENCE_FIELD_NUMBER = 39;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
     */
    public boolean hasNameReference() {
      return expressionCase_ == 39;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference getNameReference() {
      if (expressionCase_ == 39) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder getNameReferenceOrBuilder() {
      if (expressionCase_ == 39) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
    }

    public static final int PROPERTY_REFERENCE_FIELD_NUMBER = 40;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
     */
    public boolean hasPropertyReference() {
      return expressionCase_ == 40;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference getPropertyReference() {
      if (expressionCase_ == 40) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder getPropertyReferenceOrBuilder() {
      if (expressionCase_ == 40) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
    }

    public static final int INVOCATION_FIELD_NUMBER = 41;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
     */
    public boolean hasInvocation() {
      return expressionCase_ == 41;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation getInvocation() {
      if (expressionCase_ == 41) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder getInvocationOrBuilder() {
      if (expressionCase_ == 41) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
    }

    public static final int INSTANTIATION_FIELD_NUMBER = 42;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
     */
    public boolean hasInstantiation() {
      return expressionCase_ == 42;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation getInstantiation() {
      if (expressionCase_ == 42) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder getInstantiationOrBuilder() {
      if (expressionCase_ == 42) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
    }

    private void initFields() {
      fileId_ = 0;
      location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      synthetic_ = false;
      sideEffects_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects.AFFECTS_STATE;
      localAlias_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (hasLocation()) {
        if (!getLocation().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasRegExpLiteral()) {
        if (!getRegExpLiteral().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasArrayLiteral()) {
        if (!getArrayLiteral().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasObjectLiteral()) {
        if (!getObjectLiteral().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasFunction()) {
        if (!getFunction().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasDocComment()) {
        if (!getDocComment().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasBinary()) {
        if (!getBinary().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasUnary()) {
        if (!getUnary().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasConditional()) {
        if (!getConditional().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasArrayAccess()) {
        if (!getArrayAccess().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasNameReference()) {
        if (!getNameReference().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasPropertyReference()) {
        if (!getPropertyReference().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasInvocation()) {
        if (!getInvocation().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasInstantiation()) {
        if (!getInstantiation().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, fileId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, location_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, synthetic_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeEnum(4, sideEffects_.getNumber());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt32(5, localAlias_);
      }
      if (expressionCase_ == 22) {
        output.writeInt32(
            22, (int)((java.lang.Integer) expression_));
      }
      if (expressionCase_ == 23) {
        output.writeMessage(23, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_);
      }
      if (expressionCase_ == 24) {
        output.writeMessage(24, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_);
      }
      if (expressionCase_ == 25) {
        output.writeMessage(25, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_);
      }
      if (expressionCase_ == 26) {
        output.writeMessage(26, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_);
      }
      if (expressionCase_ == 27) {
        output.writeInt32(
            27, (int)((java.lang.Integer) expression_));
      }
      if (expressionCase_ == 28) {
        output.writeMessage(28, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_);
      }
      if (expressionCase_ == 29) {
        output.writeInt32(
            29, (int)((java.lang.Integer) expression_));
      }
      if (expressionCase_ == 30) {
        output.writeDouble(
            30, (double)((java.lang.Double) expression_));
      }
      if (expressionCase_ == 31) {
        output.writeMessage(31, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_);
      }
      if (expressionCase_ == 32) {
        output.writeMessage(32, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_);
      }
      if (expressionCase_ == 33) {
        output.writeMessage(33, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_);
      }
      if (expressionCase_ == 34) {
        output.writeMessage(34, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_);
      }
      if (expressionCase_ == 35) {
        output.writeMessage(35, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_);
      }
      if (expressionCase_ == 36) {
        output.writeMessage(36, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_);
      }
      if (expressionCase_ == 37) {
        output.writeMessage(37, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_);
      }
      if (expressionCase_ == 38) {
        output.writeMessage(38, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_);
      }
      if (expressionCase_ == 39) {
        output.writeMessage(39, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_);
      }
      if (expressionCase_ == 40) {
        output.writeMessage(40, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_);
      }
      if (expressionCase_ == 41) {
        output.writeMessage(41, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_);
      }
      if (expressionCase_ == 42) {
        output.writeMessage(42, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, fileId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, location_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(3, synthetic_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(4, sideEffects_.getNumber());
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(5, localAlias_);
      }
      if (expressionCase_ == 22) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(
              22, (int)((java.lang.Integer) expression_));
      }
      if (expressionCase_ == 23) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(23, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_);
      }
      if (expressionCase_ == 24) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(24, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_);
      }
      if (expressionCase_ == 25) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(25, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_);
      }
      if (expressionCase_ == 26) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(26, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_);
      }
      if (expressionCase_ == 27) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(
              27, (int)((java.lang.Integer) expression_));
      }
      if (expressionCase_ == 28) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(28, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_);
      }
      if (expressionCase_ == 29) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(
              29, (int)((java.lang.Integer) expression_));
      }
      if (expressionCase_ == 30) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeDoubleSize(
              30, (double)((java.lang.Double) expression_));
      }
      if (expressionCase_ == 31) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(31, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_);
      }
      if (expressionCase_ == 32) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(32, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_);
      }
      if (expressionCase_ == 33) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(33, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_);
      }
      if (expressionCase_ == 34) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(34, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_);
      }
      if (expressionCase_ == 35) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(35, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_);
      }
      if (expressionCase_ == 36) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(36, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_);
      }
      if (expressionCase_ == 37) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(37, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_);
      }
      if (expressionCase_ == 38) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(38, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_);
      }
      if (expressionCase_ == 39) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(39, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_);
      }
      if (expressionCase_ == 40) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(40, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_);
      }
      if (expressionCase_ == 41) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(41, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_);
      }
      if (expressionCase_ == 42) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(42, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Expression}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Expression)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getLocationFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        fileId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        synthetic_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        sideEffects_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects.AFFECTS_STATE;
        bitField0_ = (bitField0_ & ~0x00000008);
        localAlias_ = 0;
        bitField0_ = (bitField0_ & ~0x00000010);
        expressionCase_ = 0;
        expression_ = null;
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.fileId_ = fileId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (locationBuilder_ == null) {
          result.location_ = location_;
        } else {
          result.location_ = locationBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.synthetic_ = synthetic_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.sideEffects_ = sideEffects_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.localAlias_ = localAlias_;
        if (expressionCase_ == 22) {
          result.expression_ = expression_;
        }
        if (expressionCase_ == 23) {
          if (thisLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = thisLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 24) {
          if (nullLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = nullLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 25) {
          if (trueLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = trueLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 26) {
          if (falseLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = falseLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 27) {
          result.expression_ = expression_;
        }
        if (expressionCase_ == 28) {
          if (regExpLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = regExpLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 29) {
          result.expression_ = expression_;
        }
        if (expressionCase_ == 30) {
          result.expression_ = expression_;
        }
        if (expressionCase_ == 31) {
          if (arrayLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = arrayLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 32) {
          if (objectLiteralBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = objectLiteralBuilder_.build();
          }
        }
        if (expressionCase_ == 33) {
          if (functionBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = functionBuilder_.build();
          }
        }
        if (expressionCase_ == 34) {
          if (docCommentBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = docCommentBuilder_.build();
          }
        }
        if (expressionCase_ == 35) {
          if (binaryBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = binaryBuilder_.build();
          }
        }
        if (expressionCase_ == 36) {
          if (unaryBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = unaryBuilder_.build();
          }
        }
        if (expressionCase_ == 37) {
          if (conditionalBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = conditionalBuilder_.build();
          }
        }
        if (expressionCase_ == 38) {
          if (arrayAccessBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = arrayAccessBuilder_.build();
          }
        }
        if (expressionCase_ == 39) {
          if (nameReferenceBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = nameReferenceBuilder_.build();
          }
        }
        if (expressionCase_ == 40) {
          if (propertyReferenceBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = propertyReferenceBuilder_.build();
          }
        }
        if (expressionCase_ == 41) {
          if (invocationBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = invocationBuilder_.build();
          }
        }
        if (expressionCase_ == 42) {
          if (instantiationBuilder_ == null) {
            result.expression_ = expression_;
          } else {
            result.expression_ = instantiationBuilder_.build();
          }
        }
        result.bitField0_ = to_bitField0_;
        result.expressionCase_ = expressionCase_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) return this;
        if (other.hasFileId()) {
          setFileId(other.getFileId());
        }
        if (other.hasLocation()) {
          mergeLocation(other.getLocation());
        }
        if (other.hasSynthetic()) {
          setSynthetic(other.getSynthetic());
        }
        if (other.hasSideEffects()) {
          setSideEffects(other.getSideEffects());
        }
        if (other.hasLocalAlias()) {
          setLocalAlias(other.getLocalAlias());
        }
        switch (other.getExpressionCase()) {
          case SIMPLE_NAME_REFERENCE: {
            setSimpleNameReference(other.getSimpleNameReference());
            break;
          }
          case THIS_LITERAL: {
            mergeThisLiteral(other.getThisLiteral());
            break;
          }
          case NULL_LITERAL: {
            mergeNullLiteral(other.getNullLiteral());
            break;
          }
          case TRUE_LITERAL: {
            mergeTrueLiteral(other.getTrueLiteral());
            break;
          }
          case FALSE_LITERAL: {
            mergeFalseLiteral(other.getFalseLiteral());
            break;
          }
          case STRING_LITERAL: {
            setStringLiteral(other.getStringLiteral());
            break;
          }
          case REG_EXP_LITERAL: {
            mergeRegExpLiteral(other.getRegExpLiteral());
            break;
          }
          case INT_LITERAL: {
            setIntLiteral(other.getIntLiteral());
            break;
          }
          case DOUBLE_LITERAL: {
            setDoubleLiteral(other.getDoubleLiteral());
            break;
          }
          case ARRAY_LITERAL: {
            mergeArrayLiteral(other.getArrayLiteral());
            break;
          }
          case OBJECT_LITERAL: {
            mergeObjectLiteral(other.getObjectLiteral());
            break;
          }
          case FUNCTION: {
            mergeFunction(other.getFunction());
            break;
          }
          case DOC_COMMENT: {
            mergeDocComment(other.getDocComment());
            break;
          }
          case BINARY: {
            mergeBinary(other.getBinary());
            break;
          }
          case UNARY: {
            mergeUnary(other.getUnary());
            break;
          }
          case CONDITIONAL: {
            mergeConditional(other.getConditional());
            break;
          }
          case ARRAY_ACCESS: {
            mergeArrayAccess(other.getArrayAccess());
            break;
          }
          case NAME_REFERENCE: {
            mergeNameReference(other.getNameReference());
            break;
          }
          case PROPERTY_REFERENCE: {
            mergePropertyReference(other.getPropertyReference());
            break;
          }
          case INVOCATION: {
            mergeInvocation(other.getInvocation());
            break;
          }
          case INSTANTIATION: {
            mergeInstantiation(other.getInstantiation());
            break;
          }
          case EXPRESSION_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (hasLocation()) {
          if (!getLocation().isInitialized()) {
            
            return false;
          }
        }
        if (hasRegExpLiteral()) {
          if (!getRegExpLiteral().isInitialized()) {
            
            return false;
          }
        }
        if (hasArrayLiteral()) {
          if (!getArrayLiteral().isInitialized()) {
            
            return false;
          }
        }
        if (hasObjectLiteral()) {
          if (!getObjectLiteral().isInitialized()) {
            
            return false;
          }
        }
        if (hasFunction()) {
          if (!getFunction().isInitialized()) {
            
            return false;
          }
        }
        if (hasDocComment()) {
          if (!getDocComment().isInitialized()) {
            
            return false;
          }
        }
        if (hasBinary()) {
          if (!getBinary().isInitialized()) {
            
            return false;
          }
        }
        if (hasUnary()) {
          if (!getUnary().isInitialized()) {
            
            return false;
          }
        }
        if (hasConditional()) {
          if (!getConditional().isInitialized()) {
            
            return false;
          }
        }
        if (hasArrayAccess()) {
          if (!getArrayAccess().isInitialized()) {
            
            return false;
          }
        }
        if (hasNameReference()) {
          if (!getNameReference().isInitialized()) {
            
            return false;
          }
        }
        if (hasPropertyReference()) {
          if (!getPropertyReference().isInitialized()) {
            
            return false;
          }
        }
        if (hasInvocation()) {
          if (!getInvocation().isInitialized()) {
            
            return false;
          }
        }
        if (hasInstantiation()) {
          if (!getInstantiation().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int expressionCase_ = 0;
      private java.lang.Object expression_;
      public ExpressionCase
          getExpressionCase() {
        return ExpressionCase.valueOf(
            expressionCase_);
      }

      public Builder clearExpression() {
        expressionCase_ = 0;
        expression_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private int fileId_ ;
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public boolean hasFileId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public int getFileId() {
        return fileId_;
      }
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public Builder setFileId(int value) {
        bitField0_ |= 0x00000001;
        fileId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public Builder clearFileId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        fileId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> locationBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public boolean hasLocation() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
        if (locationBuilder_ == null) {
          return location_;
        } else {
          return locationBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder setLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          location_ = value;
          onChanged();
        } else {
          locationBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder setLocation(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder builderForValue) {
        if (locationBuilder_ == null) {
          location_ = builderForValue.build();
          onChanged();
        } else {
          locationBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder mergeLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              location_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance()) {
            location_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.newBuilder(location_).mergeFrom(value).buildPartial();
          } else {
            location_ = value;
          }
          onChanged();
        } else {
          locationBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder clearLocation() {
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
          onChanged();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder getLocationBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getLocationFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
        if (locationBuilder_ != null) {
          return locationBuilder_.getMessageOrBuilder();
        } else {
          return location_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> 
          getLocationFieldBuilder() {
        if (locationBuilder_ == null) {
          locationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder>(
                  getLocation(),
                  getParentForChildren(),
                  isClean());
          location_ = null;
        }
        return locationBuilder_;
      }

      private boolean synthetic_ ;
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public boolean hasSynthetic() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public boolean getSynthetic() {
        return synthetic_;
      }
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public Builder setSynthetic(boolean value) {
        bitField0_ |= 0x00000004;
        synthetic_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public Builder clearSynthetic() {
        bitField0_ = (bitField0_ & ~0x00000004);
        synthetic_ = false;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects sideEffects_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects.AFFECTS_STATE;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
       */
      public boolean hasSideEffects() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects getSideEffects() {
        return sideEffects_;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
       */
      public Builder setSideEffects(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000008;
        sideEffects_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SideEffects side_effects = 4 [default = AFFECTS_STATE];</code>
       */
      public Builder clearSideEffects() {
        bitField0_ = (bitField0_ & ~0x00000008);
        sideEffects_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SideEffects.AFFECTS_STATE;
        onChanged();
        return this;
      }

      private int localAlias_ ;
      /**
       * <code>optional int32 local_alias = 5;</code>
       */
      public boolean hasLocalAlias() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional int32 local_alias = 5;</code>
       */
      public int getLocalAlias() {
        return localAlias_;
      }
      /**
       * <code>optional int32 local_alias = 5;</code>
       */
      public Builder setLocalAlias(int value) {
        bitField0_ |= 0x00000010;
        localAlias_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 local_alias = 5;</code>
       */
      public Builder clearLocalAlias() {
        bitField0_ = (bitField0_ & ~0x00000010);
        localAlias_ = 0;
        onChanged();
        return this;
      }

      /**
       * <code>optional int32 simple_name_reference = 22;</code>
       */
      public boolean hasSimpleNameReference() {
        return expressionCase_ == 22;
      }
      /**
       * <code>optional int32 simple_name_reference = 22;</code>
       */
      public int getSimpleNameReference() {
        if (expressionCase_ == 22) {
          return (java.lang.Integer) expression_;
        }
        return 0;
      }
      /**
       * <code>optional int32 simple_name_reference = 22;</code>
       */
      public Builder setSimpleNameReference(int value) {
        expressionCase_ = 22;
        expression_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 simple_name_reference = 22;</code>
       */
      public Builder clearSimpleNameReference() {
        if (expressionCase_ == 22) {
          expressionCase_ = 0;
          expression_ = null;
          onChanged();
        }
        return this;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder> thisLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public boolean hasThisLiteral() {
        return expressionCase_ == 23;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral getThisLiteral() {
        if (thisLiteralBuilder_ == null) {
          if (expressionCase_ == 23) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 23) {
            return thisLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public Builder setThisLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral value) {
        if (thisLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          thisLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 23;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public Builder setThisLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder builderForValue) {
        if (thisLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          thisLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 23;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public Builder mergeThisLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral value) {
        if (thisLiteralBuilder_ == null) {
          if (expressionCase_ == 23 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 23) {
            thisLiteralBuilder_.mergeFrom(value);
          }
          thisLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 23;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public Builder clearThisLiteral() {
        if (thisLiteralBuilder_ == null) {
          if (expressionCase_ == 23) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 23) {
            expressionCase_ = 0;
            expression_ = null;
          }
          thisLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder getThisLiteralBuilder() {
        return getThisLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder getThisLiteralOrBuilder() {
        if ((expressionCase_ == 23) && (thisLiteralBuilder_ != null)) {
          return thisLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 23) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ThisLiteral this_literal = 23;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder> 
          getThisLiteralFieldBuilder() {
        if (thisLiteralBuilder_ == null) {
          if (!(expressionCase_ == 23)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
          }
          thisLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 23;
        return thisLiteralBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder> nullLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public boolean hasNullLiteral() {
        return expressionCase_ == 24;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral getNullLiteral() {
        if (nullLiteralBuilder_ == null) {
          if (expressionCase_ == 24) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 24) {
            return nullLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public Builder setNullLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral value) {
        if (nullLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          nullLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 24;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public Builder setNullLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder builderForValue) {
        if (nullLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          nullLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 24;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public Builder mergeNullLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral value) {
        if (nullLiteralBuilder_ == null) {
          if (expressionCase_ == 24 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 24) {
            nullLiteralBuilder_.mergeFrom(value);
          }
          nullLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 24;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public Builder clearNullLiteral() {
        if (nullLiteralBuilder_ == null) {
          if (expressionCase_ == 24) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 24) {
            expressionCase_ = 0;
            expression_ = null;
          }
          nullLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder getNullLiteralBuilder() {
        return getNullLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder getNullLiteralOrBuilder() {
        if ((expressionCase_ == 24) && (nullLiteralBuilder_ != null)) {
          return nullLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 24) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NullLiteral null_literal = 24;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder> 
          getNullLiteralFieldBuilder() {
        if (nullLiteralBuilder_ == null) {
          if (!(expressionCase_ == 24)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
          }
          nullLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 24;
        return nullLiteralBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder> trueLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public boolean hasTrueLiteral() {
        return expressionCase_ == 25;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral getTrueLiteral() {
        if (trueLiteralBuilder_ == null) {
          if (expressionCase_ == 25) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 25) {
            return trueLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public Builder setTrueLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral value) {
        if (trueLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          trueLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 25;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public Builder setTrueLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder builderForValue) {
        if (trueLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          trueLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 25;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public Builder mergeTrueLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral value) {
        if (trueLiteralBuilder_ == null) {
          if (expressionCase_ == 25 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 25) {
            trueLiteralBuilder_.mergeFrom(value);
          }
          trueLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 25;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public Builder clearTrueLiteral() {
        if (trueLiteralBuilder_ == null) {
          if (expressionCase_ == 25) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 25) {
            expressionCase_ = 0;
            expression_ = null;
          }
          trueLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder getTrueLiteralBuilder() {
        return getTrueLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder getTrueLiteralOrBuilder() {
        if ((expressionCase_ == 25) && (trueLiteralBuilder_ != null)) {
          return trueLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 25) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.TrueLiteral true_literal = 25;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder> 
          getTrueLiteralFieldBuilder() {
        if (trueLiteralBuilder_ == null) {
          if (!(expressionCase_ == 25)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
          }
          trueLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 25;
        return trueLiteralBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder> falseLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public boolean hasFalseLiteral() {
        return expressionCase_ == 26;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral getFalseLiteral() {
        if (falseLiteralBuilder_ == null) {
          if (expressionCase_ == 26) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 26) {
            return falseLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public Builder setFalseLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral value) {
        if (falseLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          falseLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 26;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public Builder setFalseLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder builderForValue) {
        if (falseLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          falseLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 26;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public Builder mergeFalseLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral value) {
        if (falseLiteralBuilder_ == null) {
          if (expressionCase_ == 26 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 26) {
            falseLiteralBuilder_.mergeFrom(value);
          }
          falseLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 26;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public Builder clearFalseLiteral() {
        if (falseLiteralBuilder_ == null) {
          if (expressionCase_ == 26) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 26) {
            expressionCase_ = 0;
            expression_ = null;
          }
          falseLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder getFalseLiteralBuilder() {
        return getFalseLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder getFalseLiteralOrBuilder() {
        if ((expressionCase_ == 26) && (falseLiteralBuilder_ != null)) {
          return falseLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 26) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.FalseLiteral false_literal = 26;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder> 
          getFalseLiteralFieldBuilder() {
        if (falseLiteralBuilder_ == null) {
          if (!(expressionCase_ == 26)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
          }
          falseLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 26;
        return falseLiteralBuilder_;
      }

      /**
       * <code>optional int32 string_literal = 27;</code>
       */
      public boolean hasStringLiteral() {
        return expressionCase_ == 27;
      }
      /**
       * <code>optional int32 string_literal = 27;</code>
       */
      public int getStringLiteral() {
        if (expressionCase_ == 27) {
          return (java.lang.Integer) expression_;
        }
        return 0;
      }
      /**
       * <code>optional int32 string_literal = 27;</code>
       */
      public Builder setStringLiteral(int value) {
        expressionCase_ = 27;
        expression_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 string_literal = 27;</code>
       */
      public Builder clearStringLiteral() {
        if (expressionCase_ == 27) {
          expressionCase_ = 0;
          expression_ = null;
          onChanged();
        }
        return this;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder> regExpLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public boolean hasRegExpLiteral() {
        return expressionCase_ == 28;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral getRegExpLiteral() {
        if (regExpLiteralBuilder_ == null) {
          if (expressionCase_ == 28) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 28) {
            return regExpLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public Builder setRegExpLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral value) {
        if (regExpLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          regExpLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 28;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public Builder setRegExpLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder builderForValue) {
        if (regExpLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          regExpLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 28;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public Builder mergeRegExpLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral value) {
        if (regExpLiteralBuilder_ == null) {
          if (expressionCase_ == 28 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 28) {
            regExpLiteralBuilder_.mergeFrom(value);
          }
          regExpLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 28;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public Builder clearRegExpLiteral() {
        if (regExpLiteralBuilder_ == null) {
          if (expressionCase_ == 28) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 28) {
            expressionCase_ = 0;
            expression_ = null;
          }
          regExpLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder getRegExpLiteralBuilder() {
        return getRegExpLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder getRegExpLiteralOrBuilder() {
        if ((expressionCase_ == 28) && (regExpLiteralBuilder_ != null)) {
          return regExpLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 28) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral reg_exp_literal = 28;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder> 
          getRegExpLiteralFieldBuilder() {
        if (regExpLiteralBuilder_ == null) {
          if (!(expressionCase_ == 28)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
          }
          regExpLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 28;
        return regExpLiteralBuilder_;
      }

      /**
       * <code>optional int32 int_literal = 29;</code>
       */
      public boolean hasIntLiteral() {
        return expressionCase_ == 29;
      }
      /**
       * <code>optional int32 int_literal = 29;</code>
       */
      public int getIntLiteral() {
        if (expressionCase_ == 29) {
          return (java.lang.Integer) expression_;
        }
        return 0;
      }
      /**
       * <code>optional int32 int_literal = 29;</code>
       */
      public Builder setIntLiteral(int value) {
        expressionCase_ = 29;
        expression_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 int_literal = 29;</code>
       */
      public Builder clearIntLiteral() {
        if (expressionCase_ == 29) {
          expressionCase_ = 0;
          expression_ = null;
          onChanged();
        }
        return this;
      }

      /**
       * <code>optional double double_literal = 30;</code>
       */
      public boolean hasDoubleLiteral() {
        return expressionCase_ == 30;
      }
      /**
       * <code>optional double double_literal = 30;</code>
       */
      public double getDoubleLiteral() {
        if (expressionCase_ == 30) {
          return (java.lang.Double) expression_;
        }
        return 0D;
      }
      /**
       * <code>optional double double_literal = 30;</code>
       */
      public Builder setDoubleLiteral(double value) {
        expressionCase_ = 30;
        expression_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double double_literal = 30;</code>
       */
      public Builder clearDoubleLiteral() {
        if (expressionCase_ == 30) {
          expressionCase_ = 0;
          expression_ = null;
          onChanged();
        }
        return this;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder> arrayLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public boolean hasArrayLiteral() {
        return expressionCase_ == 31;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral getArrayLiteral() {
        if (arrayLiteralBuilder_ == null) {
          if (expressionCase_ == 31) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 31) {
            return arrayLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public Builder setArrayLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral value) {
        if (arrayLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          arrayLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 31;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public Builder setArrayLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder builderForValue) {
        if (arrayLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          arrayLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 31;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public Builder mergeArrayLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral value) {
        if (arrayLiteralBuilder_ == null) {
          if (expressionCase_ == 31 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 31) {
            arrayLiteralBuilder_.mergeFrom(value);
          }
          arrayLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 31;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public Builder clearArrayLiteral() {
        if (arrayLiteralBuilder_ == null) {
          if (expressionCase_ == 31) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 31) {
            expressionCase_ = 0;
            expression_ = null;
          }
          arrayLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder getArrayLiteralBuilder() {
        return getArrayLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder getArrayLiteralOrBuilder() {
        if ((expressionCase_ == 31) && (arrayLiteralBuilder_ != null)) {
          return arrayLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 31) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral array_literal = 31;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder> 
          getArrayLiteralFieldBuilder() {
        if (arrayLiteralBuilder_ == null) {
          if (!(expressionCase_ == 31)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
          }
          arrayLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 31;
        return arrayLiteralBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder> objectLiteralBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public boolean hasObjectLiteral() {
        return expressionCase_ == 32;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral getObjectLiteral() {
        if (objectLiteralBuilder_ == null) {
          if (expressionCase_ == 32) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
        } else {
          if (expressionCase_ == 32) {
            return objectLiteralBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public Builder setObjectLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral value) {
        if (objectLiteralBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          objectLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 32;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public Builder setObjectLiteral(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder builderForValue) {
        if (objectLiteralBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          objectLiteralBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 32;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public Builder mergeObjectLiteral(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral value) {
        if (objectLiteralBuilder_ == null) {
          if (expressionCase_ == 32 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 32) {
            objectLiteralBuilder_.mergeFrom(value);
          }
          objectLiteralBuilder_.setMessage(value);
        }
        expressionCase_ = 32;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public Builder clearObjectLiteral() {
        if (objectLiteralBuilder_ == null) {
          if (expressionCase_ == 32) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 32) {
            expressionCase_ = 0;
            expression_ = null;
          }
          objectLiteralBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder getObjectLiteralBuilder() {
        return getObjectLiteralFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder getObjectLiteralOrBuilder() {
        if ((expressionCase_ == 32) && (objectLiteralBuilder_ != null)) {
          return objectLiteralBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 32) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral object_literal = 32;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder> 
          getObjectLiteralFieldBuilder() {
        if (objectLiteralBuilder_ == null) {
          if (!(expressionCase_ == 32)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
          }
          objectLiteralBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 32;
        return objectLiteralBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder> functionBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public boolean hasFunction() {
        return expressionCase_ == 33;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function getFunction() {
        if (functionBuilder_ == null) {
          if (expressionCase_ == 33) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
        } else {
          if (expressionCase_ == 33) {
            return functionBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public Builder setFunction(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function value) {
        if (functionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          functionBuilder_.setMessage(value);
        }
        expressionCase_ = 33;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public Builder setFunction(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder builderForValue) {
        if (functionBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          functionBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 33;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public Builder mergeFunction(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function value) {
        if (functionBuilder_ == null) {
          if (expressionCase_ == 33 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 33) {
            functionBuilder_.mergeFrom(value);
          }
          functionBuilder_.setMessage(value);
        }
        expressionCase_ = 33;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public Builder clearFunction() {
        if (functionBuilder_ == null) {
          if (expressionCase_ == 33) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 33) {
            expressionCase_ = 0;
            expression_ = null;
          }
          functionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder getFunctionBuilder() {
        return getFunctionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder getFunctionOrBuilder() {
        if ((expressionCase_ == 33) && (functionBuilder_ != null)) {
          return functionBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 33) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Function function = 33;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder> 
          getFunctionFieldBuilder() {
        if (functionBuilder_ == null) {
          if (!(expressionCase_ == 33)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
          }
          functionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 33;
        return functionBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder> docCommentBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public boolean hasDocComment() {
        return expressionCase_ == 34;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment getDocComment() {
        if (docCommentBuilder_ == null) {
          if (expressionCase_ == 34) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
        } else {
          if (expressionCase_ == 34) {
            return docCommentBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public Builder setDocComment(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment value) {
        if (docCommentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          docCommentBuilder_.setMessage(value);
        }
        expressionCase_ = 34;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public Builder setDocComment(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder builderForValue) {
        if (docCommentBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          docCommentBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 34;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public Builder mergeDocComment(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment value) {
        if (docCommentBuilder_ == null) {
          if (expressionCase_ == 34 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 34) {
            docCommentBuilder_.mergeFrom(value);
          }
          docCommentBuilder_.setMessage(value);
        }
        expressionCase_ = 34;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public Builder clearDocComment() {
        if (docCommentBuilder_ == null) {
          if (expressionCase_ == 34) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 34) {
            expressionCase_ = 0;
            expression_ = null;
          }
          docCommentBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder getDocCommentBuilder() {
        return getDocCommentFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder getDocCommentOrBuilder() {
        if ((expressionCase_ == 34) && (docCommentBuilder_ != null)) {
          return docCommentBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 34) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DocComment doc_comment = 34;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder> 
          getDocCommentFieldBuilder() {
        if (docCommentBuilder_ == null) {
          if (!(expressionCase_ == 34)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
          }
          docCommentBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 34;
        return docCommentBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder> binaryBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public boolean hasBinary() {
        return expressionCase_ == 35;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation getBinary() {
        if (binaryBuilder_ == null) {
          if (expressionCase_ == 35) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
        } else {
          if (expressionCase_ == 35) {
            return binaryBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public Builder setBinary(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation value) {
        if (binaryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          binaryBuilder_.setMessage(value);
        }
        expressionCase_ = 35;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public Builder setBinary(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder builderForValue) {
        if (binaryBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          binaryBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 35;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public Builder mergeBinary(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation value) {
        if (binaryBuilder_ == null) {
          if (expressionCase_ == 35 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 35) {
            binaryBuilder_.mergeFrom(value);
          }
          binaryBuilder_.setMessage(value);
        }
        expressionCase_ = 35;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public Builder clearBinary() {
        if (binaryBuilder_ == null) {
          if (expressionCase_ == 35) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 35) {
            expressionCase_ = 0;
            expression_ = null;
          }
          binaryBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder getBinaryBuilder() {
        return getBinaryFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder getBinaryOrBuilder() {
        if ((expressionCase_ == 35) && (binaryBuilder_ != null)) {
          return binaryBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 35) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation binary = 35;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder> 
          getBinaryFieldBuilder() {
        if (binaryBuilder_ == null) {
          if (!(expressionCase_ == 35)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
          }
          binaryBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 35;
        return binaryBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder> unaryBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public boolean hasUnary() {
        return expressionCase_ == 36;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation getUnary() {
        if (unaryBuilder_ == null) {
          if (expressionCase_ == 36) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
        } else {
          if (expressionCase_ == 36) {
            return unaryBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public Builder setUnary(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation value) {
        if (unaryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          unaryBuilder_.setMessage(value);
        }
        expressionCase_ = 36;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public Builder setUnary(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder builderForValue) {
        if (unaryBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          unaryBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 36;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public Builder mergeUnary(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation value) {
        if (unaryBuilder_ == null) {
          if (expressionCase_ == 36 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 36) {
            unaryBuilder_.mergeFrom(value);
          }
          unaryBuilder_.setMessage(value);
        }
        expressionCase_ = 36;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public Builder clearUnary() {
        if (unaryBuilder_ == null) {
          if (expressionCase_ == 36) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 36) {
            expressionCase_ = 0;
            expression_ = null;
          }
          unaryBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder getUnaryBuilder() {
        return getUnaryFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder getUnaryOrBuilder() {
        if ((expressionCase_ == 36) && (unaryBuilder_ != null)) {
          return unaryBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 36) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation unary = 36;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder> 
          getUnaryFieldBuilder() {
        if (unaryBuilder_ == null) {
          if (!(expressionCase_ == 36)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
          }
          unaryBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 36;
        return unaryBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder> conditionalBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public boolean hasConditional() {
        return expressionCase_ == 37;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional getConditional() {
        if (conditionalBuilder_ == null) {
          if (expressionCase_ == 37) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
        } else {
          if (expressionCase_ == 37) {
            return conditionalBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public Builder setConditional(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional value) {
        if (conditionalBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          conditionalBuilder_.setMessage(value);
        }
        expressionCase_ = 37;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public Builder setConditional(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder builderForValue) {
        if (conditionalBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          conditionalBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 37;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public Builder mergeConditional(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional value) {
        if (conditionalBuilder_ == null) {
          if (expressionCase_ == 37 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 37) {
            conditionalBuilder_.mergeFrom(value);
          }
          conditionalBuilder_.setMessage(value);
        }
        expressionCase_ = 37;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public Builder clearConditional() {
        if (conditionalBuilder_ == null) {
          if (expressionCase_ == 37) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 37) {
            expressionCase_ = 0;
            expression_ = null;
          }
          conditionalBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder getConditionalBuilder() {
        return getConditionalFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder getConditionalOrBuilder() {
        if ((expressionCase_ == 37) && (conditionalBuilder_ != null)) {
          return conditionalBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 37) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Conditional conditional = 37;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder> 
          getConditionalFieldBuilder() {
        if (conditionalBuilder_ == null) {
          if (!(expressionCase_ == 37)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
          }
          conditionalBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 37;
        return conditionalBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder> arrayAccessBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public boolean hasArrayAccess() {
        return expressionCase_ == 38;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess getArrayAccess() {
        if (arrayAccessBuilder_ == null) {
          if (expressionCase_ == 38) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
        } else {
          if (expressionCase_ == 38) {
            return arrayAccessBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public Builder setArrayAccess(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess value) {
        if (arrayAccessBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          arrayAccessBuilder_.setMessage(value);
        }
        expressionCase_ = 38;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public Builder setArrayAccess(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder builderForValue) {
        if (arrayAccessBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          arrayAccessBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 38;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public Builder mergeArrayAccess(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess value) {
        if (arrayAccessBuilder_ == null) {
          if (expressionCase_ == 38 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 38) {
            arrayAccessBuilder_.mergeFrom(value);
          }
          arrayAccessBuilder_.setMessage(value);
        }
        expressionCase_ = 38;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public Builder clearArrayAccess() {
        if (arrayAccessBuilder_ == null) {
          if (expressionCase_ == 38) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 38) {
            expressionCase_ = 0;
            expression_ = null;
          }
          arrayAccessBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder getArrayAccessBuilder() {
        return getArrayAccessFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder getArrayAccessOrBuilder() {
        if ((expressionCase_ == 38) && (arrayAccessBuilder_ != null)) {
          return arrayAccessBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 38) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ArrayAccess array_access = 38;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder> 
          getArrayAccessFieldBuilder() {
        if (arrayAccessBuilder_ == null) {
          if (!(expressionCase_ == 38)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
          }
          arrayAccessBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 38;
        return arrayAccessBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder> nameReferenceBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public boolean hasNameReference() {
        return expressionCase_ == 39;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference getNameReference() {
        if (nameReferenceBuilder_ == null) {
          if (expressionCase_ == 39) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
        } else {
          if (expressionCase_ == 39) {
            return nameReferenceBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public Builder setNameReference(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference value) {
        if (nameReferenceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          nameReferenceBuilder_.setMessage(value);
        }
        expressionCase_ = 39;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public Builder setNameReference(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder builderForValue) {
        if (nameReferenceBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          nameReferenceBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 39;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public Builder mergeNameReference(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference value) {
        if (nameReferenceBuilder_ == null) {
          if (expressionCase_ == 39 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 39) {
            nameReferenceBuilder_.mergeFrom(value);
          }
          nameReferenceBuilder_.setMessage(value);
        }
        expressionCase_ = 39;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public Builder clearNameReference() {
        if (nameReferenceBuilder_ == null) {
          if (expressionCase_ == 39) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 39) {
            expressionCase_ = 0;
            expression_ = null;
          }
          nameReferenceBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder getNameReferenceBuilder() {
        return getNameReferenceFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder getNameReferenceOrBuilder() {
        if ((expressionCase_ == 39) && (nameReferenceBuilder_ != null)) {
          return nameReferenceBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 39) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.NameReference name_reference = 39;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder> 
          getNameReferenceFieldBuilder() {
        if (nameReferenceBuilder_ == null) {
          if (!(expressionCase_ == 39)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
          }
          nameReferenceBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 39;
        return nameReferenceBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder> propertyReferenceBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public boolean hasPropertyReference() {
        return expressionCase_ == 40;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference getPropertyReference() {
        if (propertyReferenceBuilder_ == null) {
          if (expressionCase_ == 40) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
        } else {
          if (expressionCase_ == 40) {
            return propertyReferenceBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public Builder setPropertyReference(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference value) {
        if (propertyReferenceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          propertyReferenceBuilder_.setMessage(value);
        }
        expressionCase_ = 40;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public Builder setPropertyReference(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder builderForValue) {
        if (propertyReferenceBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          propertyReferenceBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 40;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public Builder mergePropertyReference(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference value) {
        if (propertyReferenceBuilder_ == null) {
          if (expressionCase_ == 40 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 40) {
            propertyReferenceBuilder_.mergeFrom(value);
          }
          propertyReferenceBuilder_.setMessage(value);
        }
        expressionCase_ = 40;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public Builder clearPropertyReference() {
        if (propertyReferenceBuilder_ == null) {
          if (expressionCase_ == 40) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 40) {
            expressionCase_ = 0;
            expression_ = null;
          }
          propertyReferenceBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder getPropertyReferenceBuilder() {
        return getPropertyReferenceFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder getPropertyReferenceOrBuilder() {
        if ((expressionCase_ == 40) && (propertyReferenceBuilder_ != null)) {
          return propertyReferenceBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 40) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.PropertyReference property_reference = 40;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder> 
          getPropertyReferenceFieldBuilder() {
        if (propertyReferenceBuilder_ == null) {
          if (!(expressionCase_ == 40)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
          }
          propertyReferenceBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 40;
        return propertyReferenceBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder> invocationBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public boolean hasInvocation() {
        return expressionCase_ == 41;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation getInvocation() {
        if (invocationBuilder_ == null) {
          if (expressionCase_ == 41) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
        } else {
          if (expressionCase_ == 41) {
            return invocationBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public Builder setInvocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation value) {
        if (invocationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          invocationBuilder_.setMessage(value);
        }
        expressionCase_ = 41;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public Builder setInvocation(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder builderForValue) {
        if (invocationBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          invocationBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 41;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public Builder mergeInvocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation value) {
        if (invocationBuilder_ == null) {
          if (expressionCase_ == 41 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 41) {
            invocationBuilder_.mergeFrom(value);
          }
          invocationBuilder_.setMessage(value);
        }
        expressionCase_ = 41;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public Builder clearInvocation() {
        if (invocationBuilder_ == null) {
          if (expressionCase_ == 41) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 41) {
            expressionCase_ = 0;
            expression_ = null;
          }
          invocationBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder getInvocationBuilder() {
        return getInvocationFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder getInvocationOrBuilder() {
        if ((expressionCase_ == 41) && (invocationBuilder_ != null)) {
          return invocationBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 41) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Invocation invocation = 41;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder> 
          getInvocationFieldBuilder() {
        if (invocationBuilder_ == null) {
          if (!(expressionCase_ == 41)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
          }
          invocationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 41;
        return invocationBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder> instantiationBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public boolean hasInstantiation() {
        return expressionCase_ == 42;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation getInstantiation() {
        if (instantiationBuilder_ == null) {
          if (expressionCase_ == 42) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
        } else {
          if (expressionCase_ == 42) {
            return instantiationBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public Builder setInstantiation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation value) {
        if (instantiationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          instantiationBuilder_.setMessage(value);
        }
        expressionCase_ = 42;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public Builder setInstantiation(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder builderForValue) {
        if (instantiationBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          instantiationBuilder_.setMessage(builderForValue.build());
        }
        expressionCase_ = 42;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public Builder mergeInstantiation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation value) {
        if (instantiationBuilder_ == null) {
          if (expressionCase_ == 42 &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance()) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_)
                .mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          if (expressionCase_ == 42) {
            instantiationBuilder_.mergeFrom(value);
          }
          instantiationBuilder_.setMessage(value);
        }
        expressionCase_ = 42;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public Builder clearInstantiation() {
        if (instantiationBuilder_ == null) {
          if (expressionCase_ == 42) {
            expressionCase_ = 0;
            expression_ = null;
            onChanged();
          }
        } else {
          if (expressionCase_ == 42) {
            expressionCase_ = 0;
            expression_ = null;
          }
          instantiationBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder getInstantiationBuilder() {
        return getInstantiationFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder getInstantiationOrBuilder() {
        if ((expressionCase_ == 42) && (instantiationBuilder_ != null)) {
          return instantiationBuilder_.getMessageOrBuilder();
        } else {
          if (expressionCase_ == 42) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Instantiation instantiation = 42;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder> 
          getInstantiationFieldBuilder() {
        if (instantiationBuilder_ == null) {
          if (!(expressionCase_ == 42)) {
            expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
          }
          instantiationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) expression_,
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        expressionCase_ = 42;
        return instantiationBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Expression)
    }

    static {
      defaultInstance = new Expression(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Expression)
  }

  public interface ThisLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ThisLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ThisLiteral}
   */
  public static final class ThisLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ThisLiteral)
      ThisLiteralOrBuilder {
    // Use ThisLiteral.newBuilder() to construct.
    private ThisLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ThisLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ThisLiteral defaultInstance;
    public static ThisLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public ThisLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ThisLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ThisLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ThisLiteral>() {
      public ThisLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ThisLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ThisLiteral> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ThisLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ThisLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThisLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ThisLiteral)
    }

    static {
      defaultInstance = new ThisLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ThisLiteral)
  }

  public interface NullLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.NullLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NullLiteral}
   */
  public static final class NullLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.NullLiteral)
      NullLiteralOrBuilder {
    // Use NullLiteral.newBuilder() to construct.
    private NullLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private NullLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final NullLiteral defaultInstance;
    public static NullLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public NullLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private NullLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<NullLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<NullLiteral>() {
      public NullLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new NullLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<NullLiteral> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NullLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.NullLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NullLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.NullLiteral)
    }

    static {
      defaultInstance = new NullLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.NullLiteral)
  }

  public interface TrueLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.TrueLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.TrueLiteral}
   */
  public static final class TrueLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.TrueLiteral)
      TrueLiteralOrBuilder {
    // Use TrueLiteral.newBuilder() to construct.
    private TrueLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private TrueLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final TrueLiteral defaultInstance;
    public static TrueLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public TrueLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private TrueLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<TrueLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<TrueLiteral>() {
      public TrueLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new TrueLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<TrueLiteral> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.TrueLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.TrueLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TrueLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.TrueLiteral)
    }

    static {
      defaultInstance = new TrueLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.TrueLiteral)
  }

  public interface FalseLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.FalseLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.FalseLiteral}
   */
  public static final class FalseLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.FalseLiteral)
      FalseLiteralOrBuilder {
    // Use FalseLiteral.newBuilder() to construct.
    private FalseLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private FalseLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final FalseLiteral defaultInstance;
    public static FalseLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public FalseLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private FalseLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<FalseLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<FalseLiteral>() {
      public FalseLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new FalseLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<FalseLiteral> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.FalseLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.FalseLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FalseLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.FalseLiteral)
    }

    static {
      defaultInstance = new FalseLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.FalseLiteral)
  }

  public interface RegExpLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 pattern_string_id = 1;</code>
     */
    boolean hasPatternStringId();
    /**
     * <code>required int32 pattern_string_id = 1;</code>
     */
    int getPatternStringId();

    /**
     * <code>optional int32 flags_string_id = 2;</code>
     */
    boolean hasFlagsStringId();
    /**
     * <code>optional int32 flags_string_id = 2;</code>
     */
    int getFlagsStringId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral}
   */
  public static final class RegExpLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral)
      RegExpLiteralOrBuilder {
    // Use RegExpLiteral.newBuilder() to construct.
    private RegExpLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private RegExpLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final RegExpLiteral defaultInstance;
    public static RegExpLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public RegExpLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private RegExpLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              patternStringId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              flagsStringId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<RegExpLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<RegExpLiteral>() {
      public RegExpLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new RegExpLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<RegExpLiteral> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int PATTERN_STRING_ID_FIELD_NUMBER = 1;
    private int patternStringId_;
    /**
     * <code>required int32 pattern_string_id = 1;</code>
     */
    public boolean hasPatternStringId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 pattern_string_id = 1;</code>
     */
    public int getPatternStringId() {
      return patternStringId_;
    }

    public static final int FLAGS_STRING_ID_FIELD_NUMBER = 2;
    private int flagsStringId_;
    /**
     * <code>optional int32 flags_string_id = 2;</code>
     */
    public boolean hasFlagsStringId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 flags_string_id = 2;</code>
     */
    public int getFlagsStringId() {
      return flagsStringId_;
    }

    private void initFields() {
      patternStringId_ = 0;
      flagsStringId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasPatternStringId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, patternStringId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, flagsStringId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, patternStringId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, flagsStringId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        patternStringId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        flagsStringId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.patternStringId_ = patternStringId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.flagsStringId_ = flagsStringId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral.getDefaultInstance()) return this;
        if (other.hasPatternStringId()) {
          setPatternStringId(other.getPatternStringId());
        }
        if (other.hasFlagsStringId()) {
          setFlagsStringId(other.getFlagsStringId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasPatternStringId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.RegExpLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int patternStringId_ ;
      /**
       * <code>required int32 pattern_string_id = 1;</code>
       */
      public boolean hasPatternStringId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 pattern_string_id = 1;</code>
       */
      public int getPatternStringId() {
        return patternStringId_;
      }
      /**
       * <code>required int32 pattern_string_id = 1;</code>
       */
      public Builder setPatternStringId(int value) {
        bitField0_ |= 0x00000001;
        patternStringId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 pattern_string_id = 1;</code>
       */
      public Builder clearPatternStringId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        patternStringId_ = 0;
        onChanged();
        return this;
      }

      private int flagsStringId_ ;
      /**
       * <code>optional int32 flags_string_id = 2;</code>
       */
      public boolean hasFlagsStringId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 flags_string_id = 2;</code>
       */
      public int getFlagsStringId() {
        return flagsStringId_;
      }
      /**
       * <code>optional int32 flags_string_id = 2;</code>
       */
      public Builder setFlagsStringId(int value) {
        bitField0_ |= 0x00000002;
        flagsStringId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 flags_string_id = 2;</code>
       */
      public Builder clearFlagsStringId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        flagsStringId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral)
    }

    static {
      defaultInstance = new RegExpLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.RegExpLiteral)
  }

  public interface ArrayLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> 
        getElementList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getElement(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    int getElementCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getElementOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getElementOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral}
   */
  public static final class ArrayLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral)
      ArrayLiteralOrBuilder {
    // Use ArrayLiteral.newBuilder() to construct.
    private ArrayLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ArrayLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ArrayLiteral defaultInstance;
    public static ArrayLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public ArrayLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ArrayLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                element_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>();
                mutable_bitField0_ |= 0x00000001;
              }
              element_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          element_ = java.util.Collections.unmodifiableList(element_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ArrayLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ArrayLiteral>() {
      public ArrayLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ArrayLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ArrayLiteral> getParserForType() {
      return PARSER;
    }

    public static final int ELEMENT_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> element_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getElementList() {
      return element_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getElementOrBuilderList() {
      return element_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    public int getElementCount() {
      return element_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getElement(int index) {
      return element_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getElementOrBuilder(
        int index) {
      return element_.get(index);
    }

    private void initFields() {
      element_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getElementCount(); i++) {
        if (!getElement(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < element_.size(); i++) {
        output.writeMessage(1, element_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < element_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, element_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getElementFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (elementBuilder_ == null) {
          element_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          elementBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral(this);
        int from_bitField0_ = bitField0_;
        if (elementBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            element_ = java.util.Collections.unmodifiableList(element_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.element_ = element_;
        } else {
          result.element_ = elementBuilder_.build();
        }
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral.getDefaultInstance()) return this;
        if (elementBuilder_ == null) {
          if (!other.element_.isEmpty()) {
            if (element_.isEmpty()) {
              element_ = other.element_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureElementIsMutable();
              element_.addAll(other.element_);
            }
            onChanged();
          }
        } else {
          if (!other.element_.isEmpty()) {
            if (elementBuilder_.isEmpty()) {
              elementBuilder_.dispose();
              elementBuilder_ = null;
              element_ = other.element_;
              bitField0_ = (bitField0_ & ~0x00000001);
              elementBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getElementFieldBuilder() : null;
            } else {
              elementBuilder_.addAllMessages(other.element_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getElementCount(); i++) {
          if (!getElement(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> element_ =
        java.util.Collections.emptyList();
      private void ensureElementIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          element_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>(element_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> elementBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getElementList() {
        if (elementBuilder_ == null) {
          return java.util.Collections.unmodifiableList(element_);
        } else {
          return elementBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public int getElementCount() {
        if (elementBuilder_ == null) {
          return element_.size();
        } else {
          return elementBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getElement(int index) {
        if (elementBuilder_ == null) {
          return element_.get(index);
        } else {
          return elementBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder setElement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (elementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureElementIsMutable();
          element_.set(index, value);
          onChanged();
        } else {
          elementBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder setElement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (elementBuilder_ == null) {
          ensureElementIsMutable();
          element_.set(index, builderForValue.build());
          onChanged();
        } else {
          elementBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder addElement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (elementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureElementIsMutable();
          element_.add(value);
          onChanged();
        } else {
          elementBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder addElement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (elementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureElementIsMutable();
          element_.add(index, value);
          onChanged();
        } else {
          elementBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder addElement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (elementBuilder_ == null) {
          ensureElementIsMutable();
          element_.add(builderForValue.build());
          onChanged();
        } else {
          elementBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder addElement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (elementBuilder_ == null) {
          ensureElementIsMutable();
          element_.add(index, builderForValue.build());
          onChanged();
        } else {
          elementBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder addAllElement(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> values) {
        if (elementBuilder_ == null) {
          ensureElementIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, element_);
          onChanged();
        } else {
          elementBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder clearElement() {
        if (elementBuilder_ == null) {
          element_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          elementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public Builder removeElement(int index) {
        if (elementBuilder_ == null) {
          ensureElementIsMutable();
          element_.remove(index);
          onChanged();
        } else {
          elementBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getElementBuilder(
          int index) {
        return getElementFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getElementOrBuilder(
          int index) {
        if (elementBuilder_ == null) {
          return element_.get(index);  } else {
          return elementBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
           getElementOrBuilderList() {
        if (elementBuilder_ != null) {
          return elementBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(element_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addElementBuilder() {
        return getElementFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addElementBuilder(
          int index) {
        return getElementFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression element = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder> 
           getElementBuilderList() {
        return getElementFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getElementFieldBuilder() {
        if (elementBuilder_ == null) {
          elementBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  element_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          element_ = null;
        }
        return elementBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral)
    }

    static {
      defaultInstance = new ArrayLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ArrayLiteral)
  }

  public interface ObjectLiteralOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry> 
        getEntryList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry getEntry(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    int getEntryCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder> 
        getEntryOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder getEntryOrBuilder(
        int index);

    /**
     * <code>optional bool multiline = 2 [default = true];</code>
     */
    boolean hasMultiline();
    /**
     * <code>optional bool multiline = 2 [default = true];</code>
     */
    boolean getMultiline();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral}
   */
  public static final class ObjectLiteral extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral)
      ObjectLiteralOrBuilder {
    // Use ObjectLiteral.newBuilder() to construct.
    private ObjectLiteral(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ObjectLiteral(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ObjectLiteral defaultInstance;
    public static ObjectLiteral getDefaultInstance() {
      return defaultInstance;
    }

    public ObjectLiteral getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ObjectLiteral(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                entry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry>();
                mutable_bitField0_ |= 0x00000001;
              }
              entry_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.PARSER, extensionRegistry));
              break;
            }
            case 16: {
              bitField0_ |= 0x00000001;
              multiline_ = input.readBool();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = java.util.Collections.unmodifiableList(entry_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ObjectLiteral> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ObjectLiteral>() {
      public ObjectLiteral parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ObjectLiteral(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ObjectLiteral> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int ENTRY_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry> entry_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry> getEntryList() {
      return entry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder> 
        getEntryOrBuilderList() {
      return entry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    public int getEntryCount() {
      return entry_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry getEntry(int index) {
      return entry_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder getEntryOrBuilder(
        int index) {
      return entry_.get(index);
    }

    public static final int MULTILINE_FIELD_NUMBER = 2;
    private boolean multiline_;
    /**
     * <code>optional bool multiline = 2 [default = true];</code>
     */
    public boolean hasMultiline() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional bool multiline = 2 [default = true];</code>
     */
    public boolean getMultiline() {
      return multiline_;
    }

    private void initFields() {
      entry_ = java.util.Collections.emptyList();
      multiline_ = true;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getEntryCount(); i++) {
        if (!getEntry(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < entry_.size(); i++) {
        output.writeMessage(1, entry_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(2, multiline_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < entry_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, entry_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(2, multiline_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getEntryFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (entryBuilder_ == null) {
          entry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          entryBuilder_.clear();
        }
        multiline_ = true;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (entryBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            entry_ = java.util.Collections.unmodifiableList(entry_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.entry_ = entry_;
        } else {
          result.entry_ = entryBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.multiline_ = multiline_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral.getDefaultInstance()) return this;
        if (entryBuilder_ == null) {
          if (!other.entry_.isEmpty()) {
            if (entry_.isEmpty()) {
              entry_ = other.entry_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureEntryIsMutable();
              entry_.addAll(other.entry_);
            }
            onChanged();
          }
        } else {
          if (!other.entry_.isEmpty()) {
            if (entryBuilder_.isEmpty()) {
              entryBuilder_.dispose();
              entryBuilder_ = null;
              entry_ = other.entry_;
              bitField0_ = (bitField0_ & ~0x00000001);
              entryBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getEntryFieldBuilder() : null;
            } else {
              entryBuilder_.addAllMessages(other.entry_);
            }
          }
        }
        if (other.hasMultiline()) {
          setMultiline(other.getMultiline());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getEntryCount(); i++) {
          if (!getEntry(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteral) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry> entry_ =
        java.util.Collections.emptyList();
      private void ensureEntryIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry>(entry_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder> entryBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry> getEntryList() {
        if (entryBuilder_ == null) {
          return java.util.Collections.unmodifiableList(entry_);
        } else {
          return entryBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public int getEntryCount() {
        if (entryBuilder_ == null) {
          return entry_.size();
        } else {
          return entryBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry getEntry(int index) {
        if (entryBuilder_ == null) {
          return entry_.get(index);
        } else {
          return entryBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder setEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.set(index, value);
          onChanged();
        } else {
          entryBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder setEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.set(index, builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder addEntry(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.add(value);
          onChanged();
        } else {
          entryBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder addEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.add(index, value);
          onChanged();
        } else {
          entryBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder addEntry(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.add(builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder addEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.add(index, builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder addAllEntry(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry> values) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, entry_);
          onChanged();
        } else {
          entryBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder clearEntry() {
        if (entryBuilder_ == null) {
          entry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          entryBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public Builder removeEntry(int index) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.remove(index);
          onChanged();
        } else {
          entryBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder getEntryBuilder(
          int index) {
        return getEntryFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder getEntryOrBuilder(
          int index) {
        if (entryBuilder_ == null) {
          return entry_.get(index);  } else {
          return entryBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder> 
           getEntryOrBuilderList() {
        if (entryBuilder_ != null) {
          return entryBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(entry_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder addEntryBuilder() {
        return getEntryFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder addEntryBuilder(
          int index) {
        return getEntryFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry entry = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder> 
           getEntryBuilderList() {
        return getEntryFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder> 
          getEntryFieldBuilder() {
        if (entryBuilder_ == null) {
          entryBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder>(
                  entry_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          entry_ = null;
        }
        return entryBuilder_;
      }

      private boolean multiline_ = true;
      /**
       * <code>optional bool multiline = 2 [default = true];</code>
       */
      public boolean hasMultiline() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool multiline = 2 [default = true];</code>
       */
      public boolean getMultiline() {
        return multiline_;
      }
      /**
       * <code>optional bool multiline = 2 [default = true];</code>
       */
      public Builder setMultiline(boolean value) {
        bitField0_ |= 0x00000002;
        multiline_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool multiline = 2 [default = true];</code>
       */
      public Builder clearMultiline() {
        bitField0_ = (bitField0_ & ~0x00000002);
        multiline_ = true;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral)
    }

    static {
      defaultInstance = new ObjectLiteral(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteral)
  }

  public interface ObjectLiteralEntryOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
     */
    boolean hasKey();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getKey();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getKeyOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
     */
    boolean hasValue();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getValue();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getValueOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry}
   */
  public static final class ObjectLiteralEntry extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry)
      ObjectLiteralEntryOrBuilder {
    // Use ObjectLiteralEntry.newBuilder() to construct.
    private ObjectLiteralEntry(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ObjectLiteralEntry(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ObjectLiteralEntry defaultInstance;
    public static ObjectLiteralEntry getDefaultInstance() {
      return defaultInstance;
    }

    public ObjectLiteralEntry getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ObjectLiteralEntry(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = key_.toBuilder();
              }
              key_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(key_);
                key_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = value_.toBuilder();
              }
              value_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(value_);
                value_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ObjectLiteralEntry> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ObjectLiteralEntry>() {
      public ObjectLiteralEntry parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ObjectLiteralEntry(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ObjectLiteralEntry> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int KEY_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression key_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
     */
    public boolean hasKey() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getKey() {
      return key_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getKeyOrBuilder() {
      return key_;
    }

    public static final int VALUE_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
     */
    public boolean hasValue() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getValue() {
      return value_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getValueOrBuilder() {
      return value_;
    }

    private void initFields() {
      key_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasKey()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasValue()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getKey().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getValue().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, key_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, value_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, key_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, value_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntryOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getKeyFieldBuilder();
          getValueFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (keyBuilder_ == null) {
          key_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          keyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (valueBuilder_ == null) {
          value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          valueBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (keyBuilder_ == null) {
          result.key_ = key_;
        } else {
          result.key_ = keyBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (valueBuilder_ == null) {
          result.value_ = value_;
        } else {
          result.value_ = valueBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry.getDefaultInstance()) return this;
        if (other.hasKey()) {
          mergeKey(other.getKey());
        }
        if (other.hasValue()) {
          mergeValue(other.getValue());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasKey()) {
          
          return false;
        }
        if (!hasValue()) {
          
          return false;
        }
        if (!getKey().isInitialized()) {
          
          return false;
        }
        if (!getValue().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ObjectLiteralEntry) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression key_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> keyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public boolean hasKey() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getKey() {
        if (keyBuilder_ == null) {
          return key_;
        } else {
          return keyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public Builder setKey(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (keyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          key_ = value;
          onChanged();
        } else {
          keyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public Builder setKey(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (keyBuilder_ == null) {
          key_ = builderForValue.build();
          onChanged();
        } else {
          keyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public Builder mergeKey(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (keyBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              key_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            key_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(key_).mergeFrom(value).buildPartial();
          } else {
            key_ = value;
          }
          onChanged();
        } else {
          keyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public Builder clearKey() {
        if (keyBuilder_ == null) {
          key_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          keyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getKeyBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getKeyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getKeyOrBuilder() {
        if (keyBuilder_ != null) {
          return keyBuilder_.getMessageOrBuilder();
        } else {
          return key_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression key = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getKeyFieldBuilder() {
        if (keyBuilder_ == null) {
          keyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getKey(),
                  getParentForChildren(),
                  isClean());
          key_ = null;
        }
        return keyBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> valueBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getValue() {
        if (valueBuilder_ == null) {
          return value_;
        } else {
          return valueBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public Builder setValue(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (valueBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          value_ = value;
          onChanged();
        } else {
          valueBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public Builder setValue(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (valueBuilder_ == null) {
          value_ = builderForValue.build();
          onChanged();
        } else {
          valueBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public Builder mergeValue(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (valueBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              value_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            value_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(value_).mergeFrom(value).buildPartial();
          } else {
            value_ = value;
          }
          onChanged();
        } else {
          valueBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public Builder clearValue() {
        if (valueBuilder_ == null) {
          value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          valueBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getValueBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getValueFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getValueOrBuilder() {
        if (valueBuilder_ != null) {
          return valueBuilder_.getMessageOrBuilder();
        } else {
          return value_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression value = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getValueFieldBuilder() {
        if (valueBuilder_ == null) {
          valueBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getValue(),
                  getParentForChildren(),
                  isClean());
          value_ = null;
        }
        return valueBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry)
    }

    static {
      defaultInstance = new ObjectLiteralEntry(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ObjectLiteralEntry)
  }

  public interface FunctionOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Function)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter> 
        getParameterList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getParameter(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    int getParameterCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> 
        getParameterOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder getParameterOrBuilder(
        int index);

    /**
     * <code>optional int32 name_id = 2;</code>
     */
    boolean hasNameId();
    /**
     * <code>optional int32 name_id = 2;</code>
     */
    int getNameId();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
     */
    boolean hasBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder();

    /**
     * <code>optional bool local = 4 [default = false];</code>
     */
    boolean hasLocal();
    /**
     * <code>optional bool local = 4 [default = false];</code>
     */
    boolean getLocal();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Function}
   */
  public static final class Function extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Function)
      FunctionOrBuilder {
    // Use Function.newBuilder() to construct.
    private Function(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Function(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Function defaultInstance;
    public static Function getDefaultInstance() {
      return defaultInstance;
    }

    public Function getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Function(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                parameter_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter>();
                mutable_bitField0_ |= 0x00000001;
              }
              parameter_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.PARSER, extensionRegistry));
              break;
            }
            case 16: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = body_.toBuilder();
              }
              body_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(body_);
                body_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 32: {
              bitField0_ |= 0x00000004;
              local_ = input.readBool();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          parameter_ = java.util.Collections.unmodifiableList(parameter_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Function> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Function>() {
      public Function parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Function(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Function> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int PARAMETER_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter> parameter_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter> getParameterList() {
      return parameter_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> 
        getParameterOrBuilderList() {
      return parameter_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public int getParameterCount() {
      return parameter_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getParameter(int index) {
      return parameter_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder getParameterOrBuilder(
        int index) {
      return parameter_.get(index);
    }

    public static final int NAME_ID_FIELD_NUMBER = 2;
    private int nameId_;
    /**
     * <code>optional int32 name_id = 2;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 name_id = 2;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int BODY_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
     */
    public boolean hasBody() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
      return body_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
      return body_;
    }

    public static final int LOCAL_FIELD_NUMBER = 4;
    private boolean local_;
    /**
     * <code>optional bool local = 4 [default = false];</code>
     */
    public boolean hasLocal() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool local = 4 [default = false];</code>
     */
    public boolean getLocal() {
      return local_;
    }

    private void initFields() {
      parameter_ = java.util.Collections.emptyList();
      nameId_ = 0;
      body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      local_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasBody()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getParameterCount(); i++) {
        if (!getParameter(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (!getBody().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < parameter_.size(); i++) {
        output.writeMessage(1, parameter_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(2, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(3, body_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(4, local_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < parameter_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, parameter_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, body_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(4, local_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Function}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Function)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FunctionOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getParameterFieldBuilder();
          getBodyFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (parameterBuilder_ == null) {
          parameter_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          parameterBuilder_.clear();
        }
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        local_ = false;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (parameterBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            parameter_ = java.util.Collections.unmodifiableList(parameter_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.parameter_ = parameter_;
        } else {
          result.parameter_ = parameterBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        if (bodyBuilder_ == null) {
          result.body_ = body_;
        } else {
          result.body_ = bodyBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        result.local_ = local_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function.getDefaultInstance()) return this;
        if (parameterBuilder_ == null) {
          if (!other.parameter_.isEmpty()) {
            if (parameter_.isEmpty()) {
              parameter_ = other.parameter_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureParameterIsMutable();
              parameter_.addAll(other.parameter_);
            }
            onChanged();
          }
        } else {
          if (!other.parameter_.isEmpty()) {
            if (parameterBuilder_.isEmpty()) {
              parameterBuilder_.dispose();
              parameterBuilder_ = null;
              parameter_ = other.parameter_;
              bitField0_ = (bitField0_ & ~0x00000001);
              parameterBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getParameterFieldBuilder() : null;
            } else {
              parameterBuilder_.addAllMessages(other.parameter_);
            }
          }
        }
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        if (other.hasBody()) {
          mergeBody(other.getBody());
        }
        if (other.hasLocal()) {
          setLocal(other.getLocal());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasBody()) {
          
          return false;
        }
        for (int i = 0; i < getParameterCount(); i++) {
          if (!getParameter(i).isInitialized()) {
            
            return false;
          }
        }
        if (!getBody().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Function) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter> parameter_ =
        java.util.Collections.emptyList();
      private void ensureParameterIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          parameter_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter>(parameter_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> parameterBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter> getParameterList() {
        if (parameterBuilder_ == null) {
          return java.util.Collections.unmodifiableList(parameter_);
        } else {
          return parameterBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public int getParameterCount() {
        if (parameterBuilder_ == null) {
          return parameter_.size();
        } else {
          return parameterBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getParameter(int index) {
        if (parameterBuilder_ == null) {
          return parameter_.get(index);
        } else {
          return parameterBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder setParameter(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter value) {
        if (parameterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureParameterIsMutable();
          parameter_.set(index, value);
          onChanged();
        } else {
          parameterBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder setParameter(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder builderForValue) {
        if (parameterBuilder_ == null) {
          ensureParameterIsMutable();
          parameter_.set(index, builderForValue.build());
          onChanged();
        } else {
          parameterBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder addParameter(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter value) {
        if (parameterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureParameterIsMutable();
          parameter_.add(value);
          onChanged();
        } else {
          parameterBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder addParameter(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter value) {
        if (parameterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureParameterIsMutable();
          parameter_.add(index, value);
          onChanged();
        } else {
          parameterBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder addParameter(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder builderForValue) {
        if (parameterBuilder_ == null) {
          ensureParameterIsMutable();
          parameter_.add(builderForValue.build());
          onChanged();
        } else {
          parameterBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder addParameter(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder builderForValue) {
        if (parameterBuilder_ == null) {
          ensureParameterIsMutable();
          parameter_.add(index, builderForValue.build());
          onChanged();
        } else {
          parameterBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder addAllParameter(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter> values) {
        if (parameterBuilder_ == null) {
          ensureParameterIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, parameter_);
          onChanged();
        } else {
          parameterBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder clearParameter() {
        if (parameterBuilder_ == null) {
          parameter_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          parameterBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder removeParameter(int index) {
        if (parameterBuilder_ == null) {
          ensureParameterIsMutable();
          parameter_.remove(index);
          onChanged();
        } else {
          parameterBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder getParameterBuilder(
          int index) {
        return getParameterFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder getParameterOrBuilder(
          int index) {
        if (parameterBuilder_ == null) {
          return parameter_.get(index);  } else {
          return parameterBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> 
           getParameterOrBuilderList() {
        if (parameterBuilder_ != null) {
          return parameterBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(parameter_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder addParameterBuilder() {
        return getParameterFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder addParameterBuilder(
          int index) {
        return getParameterFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder> 
           getParameterBuilderList() {
        return getParameterFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> 
          getParameterFieldBuilder() {
        if (parameterBuilder_ == null) {
          parameterBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder>(
                  parameter_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          parameter_ = null;
        }
        return parameterBuilder_;
      }

      private int nameId_ ;
      /**
       * <code>optional int32 name_id = 2;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 name_id = 2;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>optional int32 name_id = 2;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000002;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 name_id = 2;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        nameId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> bodyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public boolean hasBody() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
        if (bodyBuilder_ == null) {
          return body_;
        } else {
          return bodyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public Builder setBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          body_ = value;
          onChanged();
        } else {
          bodyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public Builder setBody(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (bodyBuilder_ == null) {
          body_ = builderForValue.build();
          onChanged();
        } else {
          bodyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public Builder mergeBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              body_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            body_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(body_).mergeFrom(value).buildPartial();
          } else {
            body_ = value;
          }
          onChanged();
        } else {
          bodyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public Builder clearBody() {
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getBodyBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getBodyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
        if (bodyBuilder_ != null) {
          return bodyBuilder_.getMessageOrBuilder();
        } else {
          return body_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getBodyFieldBuilder() {
        if (bodyBuilder_ == null) {
          bodyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getBody(),
                  getParentForChildren(),
                  isClean());
          body_ = null;
        }
        return bodyBuilder_;
      }

      private boolean local_ ;
      /**
       * <code>optional bool local = 4 [default = false];</code>
       */
      public boolean hasLocal() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional bool local = 4 [default = false];</code>
       */
      public boolean getLocal() {
        return local_;
      }
      /**
       * <code>optional bool local = 4 [default = false];</code>
       */
      public Builder setLocal(boolean value) {
        bitField0_ |= 0x00000008;
        local_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool local = 4 [default = false];</code>
       */
      public Builder clearLocal() {
        bitField0_ = (bitField0_ & ~0x00000008);
        local_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Function)
    }

    static {
      defaultInstance = new Function(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Function)
  }

  public interface ParameterOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Parameter)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 name_id = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 name_id = 1;</code>
     */
    int getNameId();

    /**
     * <code>optional bool has_default_value = 2 [default = false];</code>
     */
    boolean hasHasDefaultValue();
    /**
     * <code>optional bool has_default_value = 2 [default = false];</code>
     */
    boolean getHasDefaultValue();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Parameter}
   */
  public static final class Parameter extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Parameter)
      ParameterOrBuilder {
    // Use Parameter.newBuilder() to construct.
    private Parameter(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Parameter(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Parameter defaultInstance;
    public static Parameter getDefaultInstance() {
      return defaultInstance;
    }

    public Parameter getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Parameter(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              hasDefaultValue_ = input.readBool();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Parameter> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Parameter>() {
      public Parameter parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Parameter(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Parameter> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int NAME_ID_FIELD_NUMBER = 1;
    private int nameId_;
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int HAS_DEFAULT_VALUE_FIELD_NUMBER = 2;
    private boolean hasDefaultValue_;
    /**
     * <code>optional bool has_default_value = 2 [default = false];</code>
     */
    public boolean hasHasDefaultValue() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool has_default_value = 2 [default = false];</code>
     */
    public boolean getHasDefaultValue() {
      return hasDefaultValue_;
    }

    private void initFields() {
      nameId_ = 0;
      hasDefaultValue_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(2, hasDefaultValue_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(2, hasDefaultValue_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Parameter}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Parameter)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        hasDefaultValue_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.hasDefaultValue_ = hasDefaultValue_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance()) return this;
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        if (other.hasHasDefaultValue()) {
          setHasDefaultValue(other.getHasDefaultValue());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasNameId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int nameId_ ;
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000001;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        onChanged();
        return this;
      }

      private boolean hasDefaultValue_ ;
      /**
       * <code>optional bool has_default_value = 2 [default = false];</code>
       */
      public boolean hasHasDefaultValue() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool has_default_value = 2 [default = false];</code>
       */
      public boolean getHasDefaultValue() {
        return hasDefaultValue_;
      }
      /**
       * <code>optional bool has_default_value = 2 [default = false];</code>
       */
      public Builder setHasDefaultValue(boolean value) {
        bitField0_ |= 0x00000002;
        hasDefaultValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool has_default_value = 2 [default = false];</code>
       */
      public Builder clearHasDefaultValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        hasDefaultValue_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Parameter)
    }

    static {
      defaultInstance = new Parameter(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Parameter)
  }

  public interface DocCommentOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.DocComment)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag> 
        getTagList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag getTag(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    int getTagCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder> 
        getTagOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder getTagOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.DocComment}
   */
  public static final class DocComment extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.DocComment)
      DocCommentOrBuilder {
    // Use DocComment.newBuilder() to construct.
    private DocComment(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private DocComment(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final DocComment defaultInstance;
    public static DocComment getDefaultInstance() {
      return defaultInstance;
    }

    public DocComment getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private DocComment(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                tag_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag>();
                mutable_bitField0_ |= 0x00000001;
              }
              tag_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          tag_ = java.util.Collections.unmodifiableList(tag_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<DocComment> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<DocComment>() {
      public DocComment parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new DocComment(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<DocComment> getParserForType() {
      return PARSER;
    }

    public static final int TAG_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag> tag_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag> getTagList() {
      return tag_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder> 
        getTagOrBuilderList() {
      return tag_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    public int getTagCount() {
      return tag_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag getTag(int index) {
      return tag_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder getTagOrBuilder(
        int index) {
      return tag_.get(index);
    }

    private void initFields() {
      tag_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getTagCount(); i++) {
        if (!getTag(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < tag_.size(); i++) {
        output.writeMessage(1, tag_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < tag_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, tag_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.DocComment}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.DocComment)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getTagFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (tagBuilder_ == null) {
          tag_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          tagBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment(this);
        int from_bitField0_ = bitField0_;
        if (tagBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            tag_ = java.util.Collections.unmodifiableList(tag_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.tag_ = tag_;
        } else {
          result.tag_ = tagBuilder_.build();
        }
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment.getDefaultInstance()) return this;
        if (tagBuilder_ == null) {
          if (!other.tag_.isEmpty()) {
            if (tag_.isEmpty()) {
              tag_ = other.tag_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureTagIsMutable();
              tag_.addAll(other.tag_);
            }
            onChanged();
          }
        } else {
          if (!other.tag_.isEmpty()) {
            if (tagBuilder_.isEmpty()) {
              tagBuilder_.dispose();
              tagBuilder_ = null;
              tag_ = other.tag_;
              bitField0_ = (bitField0_ & ~0x00000001);
              tagBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getTagFieldBuilder() : null;
            } else {
              tagBuilder_.addAllMessages(other.tag_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getTagCount(); i++) {
          if (!getTag(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocComment) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag> tag_ =
        java.util.Collections.emptyList();
      private void ensureTagIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          tag_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag>(tag_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder> tagBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag> getTagList() {
        if (tagBuilder_ == null) {
          return java.util.Collections.unmodifiableList(tag_);
        } else {
          return tagBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public int getTagCount() {
        if (tagBuilder_ == null) {
          return tag_.size();
        } else {
          return tagBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag getTag(int index) {
        if (tagBuilder_ == null) {
          return tag_.get(index);
        } else {
          return tagBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder setTag(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag value) {
        if (tagBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTagIsMutable();
          tag_.set(index, value);
          onChanged();
        } else {
          tagBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder setTag(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder builderForValue) {
        if (tagBuilder_ == null) {
          ensureTagIsMutable();
          tag_.set(index, builderForValue.build());
          onChanged();
        } else {
          tagBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder addTag(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag value) {
        if (tagBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTagIsMutable();
          tag_.add(value);
          onChanged();
        } else {
          tagBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder addTag(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag value) {
        if (tagBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTagIsMutable();
          tag_.add(index, value);
          onChanged();
        } else {
          tagBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder addTag(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder builderForValue) {
        if (tagBuilder_ == null) {
          ensureTagIsMutable();
          tag_.add(builderForValue.build());
          onChanged();
        } else {
          tagBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder addTag(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder builderForValue) {
        if (tagBuilder_ == null) {
          ensureTagIsMutable();
          tag_.add(index, builderForValue.build());
          onChanged();
        } else {
          tagBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder addAllTag(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag> values) {
        if (tagBuilder_ == null) {
          ensureTagIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, tag_);
          onChanged();
        } else {
          tagBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder clearTag() {
        if (tagBuilder_ == null) {
          tag_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          tagBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public Builder removeTag(int index) {
        if (tagBuilder_ == null) {
          ensureTagIsMutable();
          tag_.remove(index);
          onChanged();
        } else {
          tagBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder getTagBuilder(
          int index) {
        return getTagFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder getTagOrBuilder(
          int index) {
        if (tagBuilder_ == null) {
          return tag_.get(index);  } else {
          return tagBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder> 
           getTagOrBuilderList() {
        if (tagBuilder_ != null) {
          return tagBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(tag_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder addTagBuilder() {
        return getTagFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder addTagBuilder(
          int index) {
        return getTagFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.DocCommentTag tag = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder> 
           getTagBuilderList() {
        return getTagFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder> 
          getTagFieldBuilder() {
        if (tagBuilder_ == null) {
          tagBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder>(
                  tag_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          tag_ = null;
        }
        return tagBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.DocComment)
    }

    static {
      defaultInstance = new DocComment(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.DocComment)
  }

  public interface DocCommentTagOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.DocCommentTag)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 name_id = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 name_id = 1;</code>
     */
    int getNameId();

    /**
     * <code>optional int32 value_string_id = 2;</code>
     */
    boolean hasValueStringId();
    /**
     * <code>optional int32 value_string_id = 2;</code>
     */
    int getValueStringId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
     */
    boolean hasExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.DocCommentTag}
   */
  public static final class DocCommentTag extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.DocCommentTag)
      DocCommentTagOrBuilder {
    // Use DocCommentTag.newBuilder() to construct.
    private DocCommentTag(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private DocCommentTag(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final DocCommentTag defaultInstance;
    public static DocCommentTag getDefaultInstance() {
      return defaultInstance;
    }

    public DocCommentTag getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private DocCommentTag(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 16: {
              valueCase_ = 2;
              value_ = input.readInt32();
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (valueCase_ == 3) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_).toBuilder();
              }
              value_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_);
                value_ = subBuilder.buildPartial();
              }
              valueCase_ = 3;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<DocCommentTag> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<DocCommentTag>() {
      public DocCommentTag parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new DocCommentTag(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<DocCommentTag> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    private int valueCase_ = 0;
    private java.lang.Object value_;
    public enum ValueCase
        implements org.jetbrains.kotlin.protobuf.Internal.EnumLite {
      VALUE_STRING_ID(2),
      EXPRESSION(3),
      VALUE_NOT_SET(0);
      private int value = 0;
      private ValueCase(int value) {
        this.value = value;
      }
      public static ValueCase valueOf(int value) {
        switch (value) {
          case 2: return VALUE_STRING_ID;
          case 3: return EXPRESSION;
          case 0: return VALUE_NOT_SET;
          default: throw new java.lang.IllegalArgumentException(
            "Value is undefined for this oneof enum.");
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public ValueCase
    getValueCase() {
      return ValueCase.valueOf(
          valueCase_);
    }

    public static final int NAME_ID_FIELD_NUMBER = 1;
    private int nameId_;
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int VALUE_STRING_ID_FIELD_NUMBER = 2;
    /**
     * <code>optional int32 value_string_id = 2;</code>
     */
    public boolean hasValueStringId() {
      return valueCase_ == 2;
    }
    /**
     * <code>optional int32 value_string_id = 2;</code>
     */
    public int getValueStringId() {
      if (valueCase_ == 2) {
        return (java.lang.Integer) value_;
      }
      return 0;
    }

    public static final int EXPRESSION_FIELD_NUMBER = 3;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
     */
    public boolean hasExpression() {
      return valueCase_ == 3;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
      if (valueCase_ == 3) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
      if (valueCase_ == 3) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }

    private void initFields() {
      nameId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasExpression()) {
        if (!getExpression().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, nameId_);
      }
      if (valueCase_ == 2) {
        output.writeInt32(
            2, (int)((java.lang.Integer) value_));
      }
      if (valueCase_ == 3) {
        output.writeMessage(3, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, nameId_);
      }
      if (valueCase_ == 2) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(
              2, (int)((java.lang.Integer) value_));
      }
      if (valueCase_ == 3) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.DocCommentTag}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.DocCommentTag)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTagOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        valueCase_ = 0;
        value_ = null;
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (valueCase_ == 2) {
          result.value_ = value_;
        }
        if (valueCase_ == 3) {
          if (expressionBuilder_ == null) {
            result.value_ = value_;
          } else {
            result.value_ = expressionBuilder_.build();
          }
        }
        result.bitField0_ = to_bitField0_;
        result.valueCase_ = valueCase_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag.getDefaultInstance()) return this;
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        switch (other.getValueCase()) {
          case VALUE_STRING_ID: {
            setValueStringId(other.getValueStringId());
            break;
          }
          case EXPRESSION: {
            mergeExpression(other.getExpression());
            break;
          }
          case VALUE_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasNameId()) {
          
          return false;
        }
        if (hasExpression()) {
          if (!getExpression().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DocCommentTag) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int valueCase_ = 0;
      private java.lang.Object value_;
      public ValueCase
          getValueCase() {
        return ValueCase.valueOf(
            valueCase_);
      }

      public Builder clearValue() {
        valueCase_ = 0;
        value_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private int nameId_ ;
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000001;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        onChanged();
        return this;
      }

      /**
       * <code>optional int32 value_string_id = 2;</code>
       */
      public boolean hasValueStringId() {
        return valueCase_ == 2;
      }
      /**
       * <code>optional int32 value_string_id = 2;</code>
       */
      public int getValueStringId() {
        if (valueCase_ == 2) {
          return (java.lang.Integer) value_;
        }
        return 0;
      }
      /**
       * <code>optional int32 value_string_id = 2;</code>
       */
      public Builder setValueStringId(int value) {
        valueCase_ = 2;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 value_string_id = 2;</code>
       */
      public Builder clearValueStringId() {
        if (valueCase_ == 2) {
          valueCase_ = 0;
          value_ = null;
          onChanged();
        }
        return this;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> expressionBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public boolean hasExpression() {
        return valueCase_ == 3;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
        if (expressionBuilder_ == null) {
          if (valueCase_ == 3) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          if (valueCase_ == 3) {
            return expressionBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          value_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        valueCase_ = 3;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          value_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        valueCase_ = 3;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (valueCase_ == 3 &&
              value_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_)
                .mergeFrom(value).buildPartial();
          } else {
            value_ = value;
          }
          onChanged();
        } else {
          if (valueCase_ == 3) {
            expressionBuilder_.mergeFrom(value);
          }
          expressionBuilder_.setMessage(value);
        }
        valueCase_ = 3;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          if (valueCase_ == 3) {
            valueCase_ = 0;
            value_ = null;
            onChanged();
          }
        } else {
          if (valueCase_ == 3) {
            valueCase_ = 0;
            value_ = null;
          }
          expressionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExpressionBuilder() {
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
        if ((valueCase_ == 3) && (expressionBuilder_ != null)) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          if (valueCase_ == 3) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          if (!(valueCase_ == 3)) {
            value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          }
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_,
                  getParentForChildren(),
                  isClean());
          value_ = null;
        }
        valueCase_ = 3;
        return expressionBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.DocCommentTag)
    }

    static {
      defaultInstance = new DocCommentTag(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.DocCommentTag)
  }

  public interface BinaryOperationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.BinaryOperation)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
     */
    boolean hasLeft();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getLeft();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getLeftOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
     */
    boolean hasRight();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getRight();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getRightOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
     */
    boolean hasType();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type getType();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.BinaryOperation}
   */
  public static final class BinaryOperation extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.BinaryOperation)
      BinaryOperationOrBuilder {
    // Use BinaryOperation.newBuilder() to construct.
    private BinaryOperation(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private BinaryOperation(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final BinaryOperation defaultInstance;
    public static BinaryOperation getDefaultInstance() {
      return defaultInstance;
    }

    public BinaryOperation getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private BinaryOperation(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = left_.toBuilder();
              }
              left_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(left_);
                left_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = right_.toBuilder();
              }
              right_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(right_);
                right_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000004;
                type_ = value;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<BinaryOperation> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<BinaryOperation>() {
      public BinaryOperation parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new BinaryOperation(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<BinaryOperation> getParserForType() {
      return PARSER;
    }

    /**
     * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type}
     */
    public enum Type
        implements org.jetbrains.kotlin.protobuf.ProtocolMessageEnum {
      /**
       * <code>MUL = 1;</code>
       */
      MUL(0, 1),
      /**
       * <code>DIV = 2;</code>
       */
      DIV(1, 2),
      /**
       * <code>MOD = 3;</code>
       */
      MOD(2, 3),
      /**
       * <code>ADD = 4;</code>
       */
      ADD(3, 4),
      /**
       * <code>SUB = 5;</code>
       */
      SUB(4, 5),
      /**
       * <code>SHL = 6;</code>
       */
      SHL(5, 6),
      /**
       * <code>SHR = 7;</code>
       */
      SHR(6, 7),
      /**
       * <code>SHRU = 8;</code>
       */
      SHRU(7, 8),
      /**
       * <code>LT = 9;</code>
       */
      LT(8, 9),
      /**
       * <code>LTE = 10;</code>
       */
      LTE(9, 10),
      /**
       * <code>GT = 11;</code>
       */
      GT(10, 11),
      /**
       * <code>GTE = 12;</code>
       */
      GTE(11, 12),
      /**
       * <code>INSTANCEOF = 13;</code>
       */
      INSTANCEOF(12, 13),
      /**
       * <code>IN = 14;</code>
       */
      IN(13, 14),
      /**
       * <code>EQ = 15;</code>
       */
      EQ(14, 15),
      /**
       * <code>NEQ = 16;</code>
       */
      NEQ(15, 16),
      /**
       * <code>REF_EQ = 17;</code>
       */
      REF_EQ(16, 17),
      /**
       * <code>REF_NEQ = 18;</code>
       */
      REF_NEQ(17, 18),
      /**
       * <code>BIT_AND = 19;</code>
       */
      BIT_AND(18, 19),
      /**
       * <code>BIT_XOR = 20;</code>
       */
      BIT_XOR(19, 20),
      /**
       * <code>BIT_OR = 21;</code>
       */
      BIT_OR(20, 21),
      /**
       * <code>AND = 22;</code>
       */
      AND(21, 22),
      /**
       * <code>OR = 23;</code>
       */
      OR(22, 23),
      /**
       * <code>ASG = 24;</code>
       */
      ASG(23, 24),
      /**
       * <code>ASG_ADD = 25;</code>
       */
      ASG_ADD(24, 25),
      /**
       * <code>ASG_SUB = 26;</code>
       */
      ASG_SUB(25, 26),
      /**
       * <code>ASG_MUL = 27;</code>
       */
      ASG_MUL(26, 27),
      /**
       * <code>ASG_DIV = 28;</code>
       */
      ASG_DIV(27, 28),
      /**
       * <code>ASG_MOD = 29;</code>
       */
      ASG_MOD(28, 29),
      /**
       * <code>ASG_SHL = 30;</code>
       */
      ASG_SHL(29, 30),
      /**
       * <code>ASG_SHR = 31;</code>
       */
      ASG_SHR(30, 31),
      /**
       * <code>ASG_SHRU = 32;</code>
       */
      ASG_SHRU(31, 32),
      /**
       * <code>ASG_BIT_AND = 33;</code>
       */
      ASG_BIT_AND(32, 33),
      /**
       * <code>ASG_BIT_OR = 34;</code>
       */
      ASG_BIT_OR(33, 34),
      /**
       * <code>ASG_BIT_XOR = 35;</code>
       */
      ASG_BIT_XOR(34, 35),
      /**
       * <code>COMMA = 36;</code>
       */
      COMMA(35, 36),
      ;

      /**
       * <code>MUL = 1;</code>
       */
      public static final int MUL_VALUE = 1;
      /**
       * <code>DIV = 2;</code>
       */
      public static final int DIV_VALUE = 2;
      /**
       * <code>MOD = 3;</code>
       */
      public static final int MOD_VALUE = 3;
      /**
       * <code>ADD = 4;</code>
       */
      public static final int ADD_VALUE = 4;
      /**
       * <code>SUB = 5;</code>
       */
      public static final int SUB_VALUE = 5;
      /**
       * <code>SHL = 6;</code>
       */
      public static final int SHL_VALUE = 6;
      /**
       * <code>SHR = 7;</code>
       */
      public static final int SHR_VALUE = 7;
      /**
       * <code>SHRU = 8;</code>
       */
      public static final int SHRU_VALUE = 8;
      /**
       * <code>LT = 9;</code>
       */
      public static final int LT_VALUE = 9;
      /**
       * <code>LTE = 10;</code>
       */
      public static final int LTE_VALUE = 10;
      /**
       * <code>GT = 11;</code>
       */
      public static final int GT_VALUE = 11;
      /**
       * <code>GTE = 12;</code>
       */
      public static final int GTE_VALUE = 12;
      /**
       * <code>INSTANCEOF = 13;</code>
       */
      public static final int INSTANCEOF_VALUE = 13;
      /**
       * <code>IN = 14;</code>
       */
      public static final int IN_VALUE = 14;
      /**
       * <code>EQ = 15;</code>
       */
      public static final int EQ_VALUE = 15;
      /**
       * <code>NEQ = 16;</code>
       */
      public static final int NEQ_VALUE = 16;
      /**
       * <code>REF_EQ = 17;</code>
       */
      public static final int REF_EQ_VALUE = 17;
      /**
       * <code>REF_NEQ = 18;</code>
       */
      public static final int REF_NEQ_VALUE = 18;
      /**
       * <code>BIT_AND = 19;</code>
       */
      public static final int BIT_AND_VALUE = 19;
      /**
       * <code>BIT_XOR = 20;</code>
       */
      public static final int BIT_XOR_VALUE = 20;
      /**
       * <code>BIT_OR = 21;</code>
       */
      public static final int BIT_OR_VALUE = 21;
      /**
       * <code>AND = 22;</code>
       */
      public static final int AND_VALUE = 22;
      /**
       * <code>OR = 23;</code>
       */
      public static final int OR_VALUE = 23;
      /**
       * <code>ASG = 24;</code>
       */
      public static final int ASG_VALUE = 24;
      /**
       * <code>ASG_ADD = 25;</code>
       */
      public static final int ASG_ADD_VALUE = 25;
      /**
       * <code>ASG_SUB = 26;</code>
       */
      public static final int ASG_SUB_VALUE = 26;
      /**
       * <code>ASG_MUL = 27;</code>
       */
      public static final int ASG_MUL_VALUE = 27;
      /**
       * <code>ASG_DIV = 28;</code>
       */
      public static final int ASG_DIV_VALUE = 28;
      /**
       * <code>ASG_MOD = 29;</code>
       */
      public static final int ASG_MOD_VALUE = 29;
      /**
       * <code>ASG_SHL = 30;</code>
       */
      public static final int ASG_SHL_VALUE = 30;
      /**
       * <code>ASG_SHR = 31;</code>
       */
      public static final int ASG_SHR_VALUE = 31;
      /**
       * <code>ASG_SHRU = 32;</code>
       */
      public static final int ASG_SHRU_VALUE = 32;
      /**
       * <code>ASG_BIT_AND = 33;</code>
       */
      public static final int ASG_BIT_AND_VALUE = 33;
      /**
       * <code>ASG_BIT_OR = 34;</code>
       */
      public static final int ASG_BIT_OR_VALUE = 34;
      /**
       * <code>ASG_BIT_XOR = 35;</code>
       */
      public static final int ASG_BIT_XOR_VALUE = 35;
      /**
       * <code>COMMA = 36;</code>
       */
      public static final int COMMA_VALUE = 36;


      public final int getNumber() { return value; }

      public static Type valueOf(int value) {
        switch (value) {
          case 1: return MUL;
          case 2: return DIV;
          case 3: return MOD;
          case 4: return ADD;
          case 5: return SUB;
          case 6: return SHL;
          case 7: return SHR;
          case 8: return SHRU;
          case 9: return LT;
          case 10: return LTE;
          case 11: return GT;
          case 12: return GTE;
          case 13: return INSTANCEOF;
          case 14: return IN;
          case 15: return EQ;
          case 16: return NEQ;
          case 17: return REF_EQ;
          case 18: return REF_NEQ;
          case 19: return BIT_AND;
          case 20: return BIT_XOR;
          case 21: return BIT_OR;
          case 22: return AND;
          case 23: return OR;
          case 24: return ASG;
          case 25: return ASG_ADD;
          case 26: return ASG_SUB;
          case 27: return ASG_MUL;
          case 28: return ASG_DIV;
          case 29: return ASG_MOD;
          case 30: return ASG_SHL;
          case 31: return ASG_SHR;
          case 32: return ASG_SHRU;
          case 33: return ASG_BIT_AND;
          case 34: return ASG_BIT_OR;
          case 35: return ASG_BIT_XOR;
          case 36: return COMMA;
          default: return null;
        }
      }

      public static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<Type>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<Type>
          internalValueMap =
            new org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<Type>() {
              public Type findValueByNumber(int number) {
                return Type.valueOf(number);
              }
            };

      public final org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(index);
      }
      public final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDescriptor().getEnumTypes().get(0);
      }

      private static final Type[] VALUES = values();

      public static Type valueOf(
          org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int index;
      private final int value;

      private Type(int index, int value) {
        this.index = index;
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type)
    }

    private int bitField0_;
    public static final int LEFT_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression left_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
     */
    public boolean hasLeft() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getLeft() {
      return left_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getLeftOrBuilder() {
      return left_;
    }

    public static final int RIGHT_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression right_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
     */
    public boolean hasRight() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getRight() {
      return right_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getRightOrBuilder() {
      return right_;
    }

    public static final int TYPE_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type type_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
     */
    public boolean hasType() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type getType() {
      return type_;
    }

    private void initFields() {
      left_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      right_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type.MUL;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasLeft()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasRight()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasType()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getLeft().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getRight().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, left_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, right_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeEnum(3, type_.getNumber());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, left_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, right_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(3, type_.getNumber());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.BinaryOperation}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.BinaryOperation)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperationOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getLeftFieldBuilder();
          getRightFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (leftBuilder_ == null) {
          left_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          leftBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (rightBuilder_ == null) {
          right_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          rightBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type.MUL;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (leftBuilder_ == null) {
          result.left_ = left_;
        } else {
          result.left_ = leftBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (rightBuilder_ == null) {
          result.right_ = right_;
        } else {
          result.right_ = rightBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.type_ = type_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.getDefaultInstance()) return this;
        if (other.hasLeft()) {
          mergeLeft(other.getLeft());
        }
        if (other.hasRight()) {
          mergeRight(other.getRight());
        }
        if (other.hasType()) {
          setType(other.getType());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasLeft()) {
          
          return false;
        }
        if (!hasRight()) {
          
          return false;
        }
        if (!hasType()) {
          
          return false;
        }
        if (!getLeft().isInitialized()) {
          
          return false;
        }
        if (!getRight().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression left_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> leftBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public boolean hasLeft() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getLeft() {
        if (leftBuilder_ == null) {
          return left_;
        } else {
          return leftBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public Builder setLeft(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (leftBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          left_ = value;
          onChanged();
        } else {
          leftBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public Builder setLeft(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (leftBuilder_ == null) {
          left_ = builderForValue.build();
          onChanged();
        } else {
          leftBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public Builder mergeLeft(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (leftBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              left_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            left_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(left_).mergeFrom(value).buildPartial();
          } else {
            left_ = value;
          }
          onChanged();
        } else {
          leftBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public Builder clearLeft() {
        if (leftBuilder_ == null) {
          left_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          leftBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getLeftBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getLeftFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getLeftOrBuilder() {
        if (leftBuilder_ != null) {
          return leftBuilder_.getMessageOrBuilder();
        } else {
          return left_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression left = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getLeftFieldBuilder() {
        if (leftBuilder_ == null) {
          leftBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getLeft(),
                  getParentForChildren(),
                  isClean());
          left_ = null;
        }
        return leftBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression right_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> rightBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public boolean hasRight() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getRight() {
        if (rightBuilder_ == null) {
          return right_;
        } else {
          return rightBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public Builder setRight(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (rightBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          right_ = value;
          onChanged();
        } else {
          rightBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public Builder setRight(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (rightBuilder_ == null) {
          right_ = builderForValue.build();
          onChanged();
        } else {
          rightBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public Builder mergeRight(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (rightBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              right_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            right_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(right_).mergeFrom(value).buildPartial();
          } else {
            right_ = value;
          }
          onChanged();
        } else {
          rightBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public Builder clearRight() {
        if (rightBuilder_ == null) {
          right_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          rightBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getRightBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getRightFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getRightOrBuilder() {
        if (rightBuilder_ != null) {
          return rightBuilder_.getMessageOrBuilder();
        } else {
          return right_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression right = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getRightFieldBuilder() {
        if (rightBuilder_ == null) {
          rightBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getRight(),
                  getParentForChildren(),
                  isClean());
          right_ = null;
        }
        return rightBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type.MUL;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type getType() {
        return type_;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
       */
      public Builder setType(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        type_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.BinaryOperation.Type type = 3;</code>
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000004);
        type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BinaryOperation.Type.MUL;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.BinaryOperation)
    }

    static {
      defaultInstance = new BinaryOperation(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.BinaryOperation)
  }

  public interface UnaryOperationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.UnaryOperation)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
     */
    boolean hasOperand();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getOperand();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getOperandOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
     */
    boolean hasType();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type getType();

    /**
     * <code>required bool postfix = 3;</code>
     */
    boolean hasPostfix();
    /**
     * <code>required bool postfix = 3;</code>
     */
    boolean getPostfix();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.UnaryOperation}
   */
  public static final class UnaryOperation extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.UnaryOperation)
      UnaryOperationOrBuilder {
    // Use UnaryOperation.newBuilder() to construct.
    private UnaryOperation(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private UnaryOperation(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final UnaryOperation defaultInstance;
    public static UnaryOperation getDefaultInstance() {
      return defaultInstance;
    }

    public UnaryOperation getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private UnaryOperation(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = operand_.toBuilder();
              }
              operand_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(operand_);
                operand_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 16: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(2, rawValue);
              } else {
                bitField0_ |= 0x00000002;
                type_ = value;
              }
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              postfix_ = input.readBool();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<UnaryOperation> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<UnaryOperation>() {
      public UnaryOperation parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new UnaryOperation(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<UnaryOperation> getParserForType() {
      return PARSER;
    }

    /**
     * Protobuf enum {@code org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type}
     */
    public enum Type
        implements org.jetbrains.kotlin.protobuf.ProtocolMessageEnum {
      /**
       * <code>BIT_NOT = 1;</code>
       */
      BIT_NOT(0, 1),
      /**
       * <code>DEC = 2;</code>
       */
      DEC(1, 2),
      /**
       * <code>DELETE = 3;</code>
       */
      DELETE(2, 3),
      /**
       * <code>INC = 4;</code>
       */
      INC(3, 4),
      /**
       * <code>NEG = 5;</code>
       */
      NEG(4, 5),
      /**
       * <code>POS = 6;</code>
       */
      POS(5, 6),
      /**
       * <code>NOT = 7;</code>
       */
      NOT(6, 7),
      /**
       * <code>TYPEOF = 8;</code>
       */
      TYPEOF(7, 8),
      /**
       * <code>VOID = 9;</code>
       */
      VOID(8, 9),
      ;

      /**
       * <code>BIT_NOT = 1;</code>
       */
      public static final int BIT_NOT_VALUE = 1;
      /**
       * <code>DEC = 2;</code>
       */
      public static final int DEC_VALUE = 2;
      /**
       * <code>DELETE = 3;</code>
       */
      public static final int DELETE_VALUE = 3;
      /**
       * <code>INC = 4;</code>
       */
      public static final int INC_VALUE = 4;
      /**
       * <code>NEG = 5;</code>
       */
      public static final int NEG_VALUE = 5;
      /**
       * <code>POS = 6;</code>
       */
      public static final int POS_VALUE = 6;
      /**
       * <code>NOT = 7;</code>
       */
      public static final int NOT_VALUE = 7;
      /**
       * <code>TYPEOF = 8;</code>
       */
      public static final int TYPEOF_VALUE = 8;
      /**
       * <code>VOID = 9;</code>
       */
      public static final int VOID_VALUE = 9;


      public final int getNumber() { return value; }

      public static Type valueOf(int value) {
        switch (value) {
          case 1: return BIT_NOT;
          case 2: return DEC;
          case 3: return DELETE;
          case 4: return INC;
          case 5: return NEG;
          case 6: return POS;
          case 7: return NOT;
          case 8: return TYPEOF;
          case 9: return VOID;
          default: return null;
        }
      }

      public static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<Type>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<Type>
          internalValueMap =
            new org.jetbrains.kotlin.protobuf.Internal.EnumLiteMap<Type>() {
              public Type findValueByNumber(int number) {
                return Type.valueOf(number);
              }
            };

      public final org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(index);
      }
      public final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final org.jetbrains.kotlin.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDescriptor().getEnumTypes().get(0);
      }

      private static final Type[] VALUES = values();

      public static Type valueOf(
          org.jetbrains.kotlin.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int index;
      private final int value;

      private Type(int index, int value) {
        this.index = index;
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type)
    }

    private int bitField0_;
    public static final int OPERAND_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression operand_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
     */
    public boolean hasOperand() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getOperand() {
      return operand_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getOperandOrBuilder() {
      return operand_;
    }

    public static final int TYPE_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type type_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
     */
    public boolean hasType() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type getType() {
      return type_;
    }

    public static final int POSTFIX_FIELD_NUMBER = 3;
    private boolean postfix_;
    /**
     * <code>required bool postfix = 3;</code>
     */
    public boolean hasPostfix() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required bool postfix = 3;</code>
     */
    public boolean getPostfix() {
      return postfix_;
    }

    private void initFields() {
      operand_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type.BIT_NOT;
      postfix_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasOperand()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasType()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasPostfix()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getOperand().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, operand_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeEnum(2, type_.getNumber());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, postfix_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, operand_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(2, type_.getNumber());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(3, postfix_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.UnaryOperation}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.UnaryOperation)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperationOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getOperandFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (operandBuilder_ == null) {
          operand_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          operandBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type.BIT_NOT;
        bitField0_ = (bitField0_ & ~0x00000002);
        postfix_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (operandBuilder_ == null) {
          result.operand_ = operand_;
        } else {
          result.operand_ = operandBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.postfix_ = postfix_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.getDefaultInstance()) return this;
        if (other.hasOperand()) {
          mergeOperand(other.getOperand());
        }
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasPostfix()) {
          setPostfix(other.getPostfix());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasOperand()) {
          
          return false;
        }
        if (!hasType()) {
          
          return false;
        }
        if (!hasPostfix()) {
          
          return false;
        }
        if (!getOperand().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression operand_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> operandBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public boolean hasOperand() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getOperand() {
        if (operandBuilder_ == null) {
          return operand_;
        } else {
          return operandBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public Builder setOperand(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (operandBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          operand_ = value;
          onChanged();
        } else {
          operandBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public Builder setOperand(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (operandBuilder_ == null) {
          operand_ = builderForValue.build();
          onChanged();
        } else {
          operandBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public Builder mergeOperand(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (operandBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              operand_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            operand_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(operand_).mergeFrom(value).buildPartial();
          } else {
            operand_ = value;
          }
          onChanged();
        } else {
          operandBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public Builder clearOperand() {
        if (operandBuilder_ == null) {
          operand_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          operandBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getOperandBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getOperandFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getOperandOrBuilder() {
        if (operandBuilder_ != null) {
          return operandBuilder_.getMessageOrBuilder();
        } else {
          return operand_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression operand = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getOperandFieldBuilder() {
        if (operandBuilder_ == null) {
          operandBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getOperand(),
                  getParentForChildren(),
                  isClean());
          operand_ = null;
        }
        return operandBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type.BIT_NOT;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type getType() {
        return type_;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
       */
      public Builder setType(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        type_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.UnaryOperation.Type type = 2;</code>
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000002);
        type_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.UnaryOperation.Type.BIT_NOT;
        onChanged();
        return this;
      }

      private boolean postfix_ ;
      /**
       * <code>required bool postfix = 3;</code>
       */
      public boolean hasPostfix() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required bool postfix = 3;</code>
       */
      public boolean getPostfix() {
        return postfix_;
      }
      /**
       * <code>required bool postfix = 3;</code>
       */
      public Builder setPostfix(boolean value) {
        bitField0_ |= 0x00000004;
        postfix_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool postfix = 3;</code>
       */
      public Builder clearPostfix() {
        bitField0_ = (bitField0_ & ~0x00000004);
        postfix_ = false;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.UnaryOperation)
    }

    static {
      defaultInstance = new UnaryOperation(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.UnaryOperation)
  }

  public interface ConditionalOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Conditional)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
     */
    boolean hasTestExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getTestExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getTestExpressionOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
     */
    boolean hasThenExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getThenExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getThenExpressionOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
     */
    boolean hasElseExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getElseExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getElseExpressionOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Conditional}
   */
  public static final class Conditional extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Conditional)
      ConditionalOrBuilder {
    // Use Conditional.newBuilder() to construct.
    private Conditional(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Conditional(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Conditional defaultInstance;
    public static Conditional getDefaultInstance() {
      return defaultInstance;
    }

    public Conditional getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Conditional(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = testExpression_.toBuilder();
              }
              testExpression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(testExpression_);
                testExpression_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = thenExpression_.toBuilder();
              }
              thenExpression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(thenExpression_);
                thenExpression_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = elseExpression_.toBuilder();
              }
              elseExpression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(elseExpression_);
                elseExpression_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Conditional> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Conditional>() {
      public Conditional parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Conditional(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Conditional> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int TEST_EXPRESSION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression testExpression_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
     */
    public boolean hasTestExpression() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getTestExpression() {
      return testExpression_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getTestExpressionOrBuilder() {
      return testExpression_;
    }

    public static final int THEN_EXPRESSION_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression thenExpression_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
     */
    public boolean hasThenExpression() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getThenExpression() {
      return thenExpression_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getThenExpressionOrBuilder() {
      return thenExpression_;
    }

    public static final int ELSE_EXPRESSION_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression elseExpression_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
     */
    public boolean hasElseExpression() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getElseExpression() {
      return elseExpression_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getElseExpressionOrBuilder() {
      return elseExpression_;
    }

    private void initFields() {
      testExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      thenExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      elseExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasTestExpression()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasThenExpression()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasElseExpression()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getTestExpression().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getThenExpression().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getElseExpression().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, testExpression_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, thenExpression_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, elseExpression_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, testExpression_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, thenExpression_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, elseExpression_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Conditional}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Conditional)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ConditionalOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getTestExpressionFieldBuilder();
          getThenExpressionFieldBuilder();
          getElseExpressionFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (testExpressionBuilder_ == null) {
          testExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          testExpressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (thenExpressionBuilder_ == null) {
          thenExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          thenExpressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (elseExpressionBuilder_ == null) {
          elseExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          elseExpressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (testExpressionBuilder_ == null) {
          result.testExpression_ = testExpression_;
        } else {
          result.testExpression_ = testExpressionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (thenExpressionBuilder_ == null) {
          result.thenExpression_ = thenExpression_;
        } else {
          result.thenExpression_ = thenExpressionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (elseExpressionBuilder_ == null) {
          result.elseExpression_ = elseExpression_;
        } else {
          result.elseExpression_ = elseExpressionBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional.getDefaultInstance()) return this;
        if (other.hasTestExpression()) {
          mergeTestExpression(other.getTestExpression());
        }
        if (other.hasThenExpression()) {
          mergeThenExpression(other.getThenExpression());
        }
        if (other.hasElseExpression()) {
          mergeElseExpression(other.getElseExpression());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTestExpression()) {
          
          return false;
        }
        if (!hasThenExpression()) {
          
          return false;
        }
        if (!hasElseExpression()) {
          
          return false;
        }
        if (!getTestExpression().isInitialized()) {
          
          return false;
        }
        if (!getThenExpression().isInitialized()) {
          
          return false;
        }
        if (!getElseExpression().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Conditional) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression testExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> testExpressionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public boolean hasTestExpression() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getTestExpression() {
        if (testExpressionBuilder_ == null) {
          return testExpression_;
        } else {
          return testExpressionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public Builder setTestExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (testExpressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          testExpression_ = value;
          onChanged();
        } else {
          testExpressionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public Builder setTestExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (testExpressionBuilder_ == null) {
          testExpression_ = builderForValue.build();
          onChanged();
        } else {
          testExpressionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public Builder mergeTestExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (testExpressionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              testExpression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            testExpression_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(testExpression_).mergeFrom(value).buildPartial();
          } else {
            testExpression_ = value;
          }
          onChanged();
        } else {
          testExpressionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public Builder clearTestExpression() {
        if (testExpressionBuilder_ == null) {
          testExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          testExpressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getTestExpressionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getTestExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getTestExpressionOrBuilder() {
        if (testExpressionBuilder_ != null) {
          return testExpressionBuilder_.getMessageOrBuilder();
        } else {
          return testExpression_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression test_expression = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getTestExpressionFieldBuilder() {
        if (testExpressionBuilder_ == null) {
          testExpressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getTestExpression(),
                  getParentForChildren(),
                  isClean());
          testExpression_ = null;
        }
        return testExpressionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression thenExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> thenExpressionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public boolean hasThenExpression() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getThenExpression() {
        if (thenExpressionBuilder_ == null) {
          return thenExpression_;
        } else {
          return thenExpressionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public Builder setThenExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (thenExpressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          thenExpression_ = value;
          onChanged();
        } else {
          thenExpressionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public Builder setThenExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (thenExpressionBuilder_ == null) {
          thenExpression_ = builderForValue.build();
          onChanged();
        } else {
          thenExpressionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public Builder mergeThenExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (thenExpressionBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              thenExpression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            thenExpression_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(thenExpression_).mergeFrom(value).buildPartial();
          } else {
            thenExpression_ = value;
          }
          onChanged();
        } else {
          thenExpressionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public Builder clearThenExpression() {
        if (thenExpressionBuilder_ == null) {
          thenExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          thenExpressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getThenExpressionBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getThenExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getThenExpressionOrBuilder() {
        if (thenExpressionBuilder_ != null) {
          return thenExpressionBuilder_.getMessageOrBuilder();
        } else {
          return thenExpression_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression then_expression = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getThenExpressionFieldBuilder() {
        if (thenExpressionBuilder_ == null) {
          thenExpressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getThenExpression(),
                  getParentForChildren(),
                  isClean());
          thenExpression_ = null;
        }
        return thenExpressionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression elseExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> elseExpressionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public boolean hasElseExpression() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getElseExpression() {
        if (elseExpressionBuilder_ == null) {
          return elseExpression_;
        } else {
          return elseExpressionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public Builder setElseExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (elseExpressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          elseExpression_ = value;
          onChanged();
        } else {
          elseExpressionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public Builder setElseExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (elseExpressionBuilder_ == null) {
          elseExpression_ = builderForValue.build();
          onChanged();
        } else {
          elseExpressionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public Builder mergeElseExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (elseExpressionBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              elseExpression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            elseExpression_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(elseExpression_).mergeFrom(value).buildPartial();
          } else {
            elseExpression_ = value;
          }
          onChanged();
        } else {
          elseExpressionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public Builder clearElseExpression() {
        if (elseExpressionBuilder_ == null) {
          elseExpression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          elseExpressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getElseExpressionBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getElseExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getElseExpressionOrBuilder() {
        if (elseExpressionBuilder_ != null) {
          return elseExpressionBuilder_.getMessageOrBuilder();
        } else {
          return elseExpression_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression else_expression = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getElseExpressionFieldBuilder() {
        if (elseExpressionBuilder_ == null) {
          elseExpressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getElseExpression(),
                  getParentForChildren(),
                  isClean());
          elseExpression_ = null;
        }
        return elseExpressionBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Conditional)
    }

    static {
      defaultInstance = new Conditional(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Conditional)
  }

  public interface ArrayAccessOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ArrayAccess)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
     */
    boolean hasArray();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArray();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArrayOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
     */
    boolean hasIndex();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIndex();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIndexOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ArrayAccess}
   */
  public static final class ArrayAccess extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ArrayAccess)
      ArrayAccessOrBuilder {
    // Use ArrayAccess.newBuilder() to construct.
    private ArrayAccess(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ArrayAccess(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ArrayAccess defaultInstance;
    public static ArrayAccess getDefaultInstance() {
      return defaultInstance;
    }

    public ArrayAccess getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ArrayAccess(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = array_.toBuilder();
              }
              array_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(array_);
                array_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = index_.toBuilder();
              }
              index_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(index_);
                index_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ArrayAccess> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ArrayAccess>() {
      public ArrayAccess parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ArrayAccess(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ArrayAccess> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int ARRAY_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression array_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
     */
    public boolean hasArray() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArray() {
      return array_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArrayOrBuilder() {
      return array_;
    }

    public static final int INDEX_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression index_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
     */
    public boolean hasIndex() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIndex() {
      return index_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIndexOrBuilder() {
      return index_;
    }

    private void initFields() {
      array_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      index_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasArray()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasIndex()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getArray().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getIndex().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, array_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, index_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, array_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, index_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ArrayAccess}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ArrayAccess)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccessOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getArrayFieldBuilder();
          getIndexFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (arrayBuilder_ == null) {
          array_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          arrayBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (indexBuilder_ == null) {
          index_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          indexBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (arrayBuilder_ == null) {
          result.array_ = array_;
        } else {
          result.array_ = arrayBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (indexBuilder_ == null) {
          result.index_ = index_;
        } else {
          result.index_ = indexBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess.getDefaultInstance()) return this;
        if (other.hasArray()) {
          mergeArray(other.getArray());
        }
        if (other.hasIndex()) {
          mergeIndex(other.getIndex());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasArray()) {
          
          return false;
        }
        if (!hasIndex()) {
          
          return false;
        }
        if (!getArray().isInitialized()) {
          
          return false;
        }
        if (!getIndex().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ArrayAccess) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression array_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> arrayBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public boolean hasArray() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArray() {
        if (arrayBuilder_ == null) {
          return array_;
        } else {
          return arrayBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public Builder setArray(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (arrayBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          array_ = value;
          onChanged();
        } else {
          arrayBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public Builder setArray(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (arrayBuilder_ == null) {
          array_ = builderForValue.build();
          onChanged();
        } else {
          arrayBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public Builder mergeArray(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (arrayBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              array_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            array_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(array_).mergeFrom(value).buildPartial();
          } else {
            array_ = value;
          }
          onChanged();
        } else {
          arrayBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public Builder clearArray() {
        if (arrayBuilder_ == null) {
          array_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          arrayBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getArrayBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getArrayFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArrayOrBuilder() {
        if (arrayBuilder_ != null) {
          return arrayBuilder_.getMessageOrBuilder();
        } else {
          return array_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression array = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getArrayFieldBuilder() {
        if (arrayBuilder_ == null) {
          arrayBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getArray(),
                  getParentForChildren(),
                  isClean());
          array_ = null;
        }
        return arrayBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression index_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> indexBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public boolean hasIndex() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIndex() {
        if (indexBuilder_ == null) {
          return index_;
        } else {
          return indexBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public Builder setIndex(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (indexBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          index_ = value;
          onChanged();
        } else {
          indexBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public Builder setIndex(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (indexBuilder_ == null) {
          index_ = builderForValue.build();
          onChanged();
        } else {
          indexBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public Builder mergeIndex(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (indexBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              index_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            index_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(index_).mergeFrom(value).buildPartial();
          } else {
            index_ = value;
          }
          onChanged();
        } else {
          indexBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public Builder clearIndex() {
        if (indexBuilder_ == null) {
          index_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          indexBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getIndexBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getIndexFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIndexOrBuilder() {
        if (indexBuilder_ != null) {
          return indexBuilder_.getMessageOrBuilder();
        } else {
          return index_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression index = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getIndexFieldBuilder() {
        if (indexBuilder_ == null) {
          indexBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getIndex(),
                  getParentForChildren(),
                  isClean());
          index_ = null;
        }
        return indexBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ArrayAccess)
    }

    static {
      defaultInstance = new ArrayAccess(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ArrayAccess)
  }

  public interface NameReferenceOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.NameReference)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 name_id = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 name_id = 1;</code>
     */
    int getNameId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    boolean hasQualifier();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    boolean hasInlineStrategy();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NameReference}
   */
  public static final class NameReference extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.NameReference)
      NameReferenceOrBuilder {
    // Use NameReference.newBuilder() to construct.
    private NameReference(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private NameReference(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final NameReference defaultInstance;
    public static NameReference getDefaultInstance() {
      return defaultInstance;
    }

    public NameReference getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private NameReference(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = qualifier_.toBuilder();
              }
              qualifier_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(qualifier_);
                qualifier_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000004;
                inlineStrategy_ = value;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<NameReference> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<NameReference>() {
      public NameReference parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new NameReference(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<NameReference> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int NAME_ID_FIELD_NUMBER = 1;
    private int nameId_;
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int QUALIFIER_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
      return qualifier_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
      return qualifier_;
    }

    public static final int INLINE_STRATEGY_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy inlineStrategy_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    public boolean hasInlineStrategy() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy() {
      return inlineStrategy_;
    }

    private void initFields() {
      nameId_ = 0;
      qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasQualifier()) {
        if (!getQualifier().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, qualifier_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeEnum(3, inlineStrategy_.getNumber());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, qualifier_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(3, inlineStrategy_.getNumber());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NameReference}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.NameReference)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReferenceOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getQualifierFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (qualifierBuilder_ == null) {
          result.qualifier_ = qualifier_;
        } else {
          result.qualifier_ = qualifierBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.inlineStrategy_ = inlineStrategy_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference.getDefaultInstance()) return this;
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        if (other.hasQualifier()) {
          mergeQualifier(other.getQualifier());
        }
        if (other.hasInlineStrategy()) {
          setInlineStrategy(other.getInlineStrategy());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasNameId()) {
          
          return false;
        }
        if (hasQualifier()) {
          if (!getQualifier().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameReference) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int nameId_ ;
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000001;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> qualifierBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
        if (qualifierBuilder_ == null) {
          return qualifier_;
        } else {
          return qualifierBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder setQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          qualifier_ = value;
          onChanged();
        } else {
          qualifierBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder setQualifier(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (qualifierBuilder_ == null) {
          qualifier_ = builderForValue.build();
          onChanged();
        } else {
          qualifierBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder mergeQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              qualifier_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            qualifier_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(qualifier_).mergeFrom(value).buildPartial();
          } else {
            qualifier_ = value;
          }
          onChanged();
        } else {
          qualifierBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder clearQualifier() {
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getQualifierBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getQualifierFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
        if (qualifierBuilder_ != null) {
          return qualifierBuilder_.getMessageOrBuilder();
        } else {
          return qualifier_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getQualifierFieldBuilder() {
        if (qualifierBuilder_ == null) {
          qualifierBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getQualifier(),
                  getParentForChildren(),
                  isClean());
          qualifier_ = null;
        }
        return qualifierBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public boolean hasInlineStrategy() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy() {
        return inlineStrategy_;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public Builder setInlineStrategy(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        inlineStrategy_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public Builder clearInlineStrategy() {
        bitField0_ = (bitField0_ & ~0x00000004);
        inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.NameReference)
    }

    static {
      defaultInstance = new NameReference(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.NameReference)
  }

  public interface PropertyReferenceOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.PropertyReference)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 string_id = 1;</code>
     */
    boolean hasStringId();
    /**
     * <code>required int32 string_id = 1;</code>
     */
    int getStringId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    boolean hasQualifier();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    boolean hasInlineStrategy();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.PropertyReference}
   */
  public static final class PropertyReference extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.PropertyReference)
      PropertyReferenceOrBuilder {
    // Use PropertyReference.newBuilder() to construct.
    private PropertyReference(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private PropertyReference(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final PropertyReference defaultInstance;
    public static PropertyReference getDefaultInstance() {
      return defaultInstance;
    }

    public PropertyReference getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private PropertyReference(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              stringId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = qualifier_.toBuilder();
              }
              qualifier_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(qualifier_);
                qualifier_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000004;
                inlineStrategy_ = value;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<PropertyReference> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<PropertyReference>() {
      public PropertyReference parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new PropertyReference(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<PropertyReference> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int STRING_ID_FIELD_NUMBER = 1;
    private int stringId_;
    /**
     * <code>required int32 string_id = 1;</code>
     */
    public boolean hasStringId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 string_id = 1;</code>
     */
    public int getStringId() {
      return stringId_;
    }

    public static final int QUALIFIER_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
      return qualifier_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
      return qualifier_;
    }

    public static final int INLINE_STRATEGY_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy inlineStrategy_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    public boolean hasInlineStrategy() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy() {
      return inlineStrategy_;
    }

    private void initFields() {
      stringId_ = 0;
      qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasStringId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasQualifier()) {
        if (!getQualifier().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, stringId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, qualifier_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeEnum(3, inlineStrategy_.getNumber());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, stringId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, qualifier_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(3, inlineStrategy_.getNumber());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.PropertyReference}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.PropertyReference)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReferenceOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getQualifierFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        stringId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.stringId_ = stringId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (qualifierBuilder_ == null) {
          result.qualifier_ = qualifier_;
        } else {
          result.qualifier_ = qualifierBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.inlineStrategy_ = inlineStrategy_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference.getDefaultInstance()) return this;
        if (other.hasStringId()) {
          setStringId(other.getStringId());
        }
        if (other.hasQualifier()) {
          mergeQualifier(other.getQualifier());
        }
        if (other.hasInlineStrategy()) {
          setInlineStrategy(other.getInlineStrategy());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasStringId()) {
          
          return false;
        }
        if (hasQualifier()) {
          if (!getQualifier().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.PropertyReference) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int stringId_ ;
      /**
       * <code>required int32 string_id = 1;</code>
       */
      public boolean hasStringId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 string_id = 1;</code>
       */
      public int getStringId() {
        return stringId_;
      }
      /**
       * <code>required int32 string_id = 1;</code>
       */
      public Builder setStringId(int value) {
        bitField0_ |= 0x00000001;
        stringId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 string_id = 1;</code>
       */
      public Builder clearStringId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        stringId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> qualifierBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
        if (qualifierBuilder_ == null) {
          return qualifier_;
        } else {
          return qualifierBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder setQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          qualifier_ = value;
          onChanged();
        } else {
          qualifierBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder setQualifier(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (qualifierBuilder_ == null) {
          qualifier_ = builderForValue.build();
          onChanged();
        } else {
          qualifierBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder mergeQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              qualifier_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            qualifier_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(qualifier_).mergeFrom(value).buildPartial();
          } else {
            qualifier_ = value;
          }
          onChanged();
        } else {
          qualifierBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public Builder clearQualifier() {
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getQualifierBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getQualifierFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
        if (qualifierBuilder_ != null) {
          return qualifierBuilder_.getMessageOrBuilder();
        } else {
          return qualifier_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getQualifierFieldBuilder() {
        if (qualifierBuilder_ == null) {
          qualifierBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getQualifier(),
                  getParentForChildren(),
                  isClean());
          qualifier_ = null;
        }
        return qualifierBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public boolean hasInlineStrategy() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy() {
        return inlineStrategy_;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public Builder setInlineStrategy(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        inlineStrategy_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public Builder clearInlineStrategy() {
        bitField0_ = (bitField0_ & ~0x00000004);
        inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.PropertyReference)
    }

    static {
      defaultInstance = new PropertyReference(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.PropertyReference)
  }

  public interface InvocationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Invocation)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    boolean hasQualifier();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder();

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> 
        getArgumentList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArgument(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    int getArgumentCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getArgumentOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArgumentOrBuilder(
        int index);

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    boolean hasInlineStrategy();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Invocation}
   */
  public static final class Invocation extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Invocation)
      InvocationOrBuilder {
    // Use Invocation.newBuilder() to construct.
    private Invocation(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Invocation(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Invocation defaultInstance;
    public static Invocation getDefaultInstance() {
      return defaultInstance;
    }

    public Invocation getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Invocation(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = qualifier_.toBuilder();
              }
              qualifier_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(qualifier_);
                qualifier_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                argument_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>();
                mutable_bitField0_ |= 0x00000002;
              }
              argument_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry));
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000002;
                inlineStrategy_ = value;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          argument_ = java.util.Collections.unmodifiableList(argument_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Invocation> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Invocation>() {
      public Invocation parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Invocation(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Invocation> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int QUALIFIER_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
      return qualifier_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
      return qualifier_;
    }

    public static final int ARGUMENT_FIELD_NUMBER = 2;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> argument_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getArgumentList() {
      return argument_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getArgumentOrBuilderList() {
      return argument_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public int getArgumentCount() {
      return argument_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArgument(int index) {
      return argument_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArgumentOrBuilder(
        int index) {
      return argument_.get(index);
    }

    public static final int INLINE_STRATEGY_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy inlineStrategy_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    public boolean hasInlineStrategy() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy() {
      return inlineStrategy_;
    }

    private void initFields() {
      qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      argument_ = java.util.Collections.emptyList();
      inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasQualifier()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getQualifier().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getArgumentCount(); i++) {
        if (!getArgument(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, qualifier_);
      }
      for (int i = 0; i < argument_.size(); i++) {
        output.writeMessage(2, argument_.get(i));
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeEnum(3, inlineStrategy_.getNumber());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, qualifier_);
      }
      for (int i = 0; i < argument_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, argument_.get(i));
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(3, inlineStrategy_.getNumber());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Invocation}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Invocation)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InvocationOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getQualifierFieldBuilder();
          getArgumentFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (argumentBuilder_ == null) {
          argument_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          argumentBuilder_.clear();
        }
        inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (qualifierBuilder_ == null) {
          result.qualifier_ = qualifier_;
        } else {
          result.qualifier_ = qualifierBuilder_.build();
        }
        if (argumentBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            argument_ = java.util.Collections.unmodifiableList(argument_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.argument_ = argument_;
        } else {
          result.argument_ = argumentBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.inlineStrategy_ = inlineStrategy_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation.getDefaultInstance()) return this;
        if (other.hasQualifier()) {
          mergeQualifier(other.getQualifier());
        }
        if (argumentBuilder_ == null) {
          if (!other.argument_.isEmpty()) {
            if (argument_.isEmpty()) {
              argument_ = other.argument_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureArgumentIsMutable();
              argument_.addAll(other.argument_);
            }
            onChanged();
          }
        } else {
          if (!other.argument_.isEmpty()) {
            if (argumentBuilder_.isEmpty()) {
              argumentBuilder_.dispose();
              argumentBuilder_ = null;
              argument_ = other.argument_;
              bitField0_ = (bitField0_ & ~0x00000002);
              argumentBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getArgumentFieldBuilder() : null;
            } else {
              argumentBuilder_.addAllMessages(other.argument_);
            }
          }
        }
        if (other.hasInlineStrategy()) {
          setInlineStrategy(other.getInlineStrategy());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasQualifier()) {
          
          return false;
        }
        if (!getQualifier().isInitialized()) {
          
          return false;
        }
        for (int i = 0; i < getArgumentCount(); i++) {
          if (!getArgument(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Invocation) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> qualifierBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
        if (qualifierBuilder_ == null) {
          return qualifier_;
        } else {
          return qualifierBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder setQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          qualifier_ = value;
          onChanged();
        } else {
          qualifierBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder setQualifier(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (qualifierBuilder_ == null) {
          qualifier_ = builderForValue.build();
          onChanged();
        } else {
          qualifierBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder mergeQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              qualifier_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            qualifier_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(qualifier_).mergeFrom(value).buildPartial();
          } else {
            qualifier_ = value;
          }
          onChanged();
        } else {
          qualifierBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder clearQualifier() {
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getQualifierBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getQualifierFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
        if (qualifierBuilder_ != null) {
          return qualifierBuilder_.getMessageOrBuilder();
        } else {
          return qualifier_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getQualifierFieldBuilder() {
        if (qualifierBuilder_ == null) {
          qualifierBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getQualifier(),
                  getParentForChildren(),
                  isClean());
          qualifier_ = null;
        }
        return qualifierBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> argument_ =
        java.util.Collections.emptyList();
      private void ensureArgumentIsMutable() {
        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
          argument_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>(argument_);
          bitField0_ |= 0x00000002;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> argumentBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getArgumentList() {
        if (argumentBuilder_ == null) {
          return java.util.Collections.unmodifiableList(argument_);
        } else {
          return argumentBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public int getArgumentCount() {
        if (argumentBuilder_ == null) {
          return argument_.size();
        } else {
          return argumentBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArgument(int index) {
        if (argumentBuilder_ == null) {
          return argument_.get(index);
        } else {
          return argumentBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder setArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (argumentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureArgumentIsMutable();
          argument_.set(index, value);
          onChanged();
        } else {
          argumentBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder setArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.set(index, builderForValue.build());
          onChanged();
        } else {
          argumentBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (argumentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureArgumentIsMutable();
          argument_.add(value);
          onChanged();
        } else {
          argumentBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (argumentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureArgumentIsMutable();
          argument_.add(index, value);
          onChanged();
        } else {
          argumentBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.add(builderForValue.build());
          onChanged();
        } else {
          argumentBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.add(index, builderForValue.build());
          onChanged();
        } else {
          argumentBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addAllArgument(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> values) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, argument_);
          onChanged();
        } else {
          argumentBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder clearArgument() {
        if (argumentBuilder_ == null) {
          argument_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          argumentBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder removeArgument(int index) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.remove(index);
          onChanged();
        } else {
          argumentBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getArgumentBuilder(
          int index) {
        return getArgumentFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArgumentOrBuilder(
          int index) {
        if (argumentBuilder_ == null) {
          return argument_.get(index);  } else {
          return argumentBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
           getArgumentOrBuilderList() {
        if (argumentBuilder_ != null) {
          return argumentBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(argument_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addArgumentBuilder() {
        return getArgumentFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addArgumentBuilder(
          int index) {
        return getArgumentFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder> 
           getArgumentBuilderList() {
        return getArgumentFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getArgumentFieldBuilder() {
        if (argumentBuilder_ == null) {
          argumentBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  argument_,
                  ((bitField0_ & 0x00000002) == 0x00000002),
                  getParentForChildren(),
                  isClean());
          argument_ = null;
        }
        return argumentBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public boolean hasInlineStrategy() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy getInlineStrategy() {
        return inlineStrategy_;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public Builder setInlineStrategy(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        inlineStrategy_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.InlineStrategy inline_strategy = 3 [default = NOT_INLINE];</code>
       */
      public Builder clearInlineStrategy() {
        bitField0_ = (bitField0_ & ~0x00000004);
        inlineStrategy_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineStrategy.NOT_INLINE;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Invocation)
    }

    static {
      defaultInstance = new Invocation(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Invocation)
  }

  public interface InstantiationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Instantiation)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    boolean hasQualifier();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder();

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> 
        getArgumentList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArgument(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    int getArgumentCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getArgumentOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArgumentOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Instantiation}
   */
  public static final class Instantiation extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Instantiation)
      InstantiationOrBuilder {
    // Use Instantiation.newBuilder() to construct.
    private Instantiation(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Instantiation(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Instantiation defaultInstance;
    public static Instantiation getDefaultInstance() {
      return defaultInstance;
    }

    public Instantiation getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Instantiation(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = qualifier_.toBuilder();
              }
              qualifier_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(qualifier_);
                qualifier_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                argument_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>();
                mutable_bitField0_ |= 0x00000002;
              }
              argument_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          argument_ = java.util.Collections.unmodifiableList(argument_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Instantiation> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Instantiation>() {
      public Instantiation parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Instantiation(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Instantiation> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int QUALIFIER_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    public boolean hasQualifier() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
      return qualifier_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
      return qualifier_;
    }

    public static final int ARGUMENT_FIELD_NUMBER = 2;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> argument_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getArgumentList() {
      return argument_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getArgumentOrBuilderList() {
      return argument_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public int getArgumentCount() {
      return argument_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArgument(int index) {
      return argument_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArgumentOrBuilder(
        int index) {
      return argument_.get(index);
    }

    private void initFields() {
      qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      argument_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasQualifier()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getQualifier().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getArgumentCount(); i++) {
        if (!getArgument(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, qualifier_);
      }
      for (int i = 0; i < argument_.size(); i++) {
        output.writeMessage(2, argument_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, qualifier_);
      }
      for (int i = 0; i < argument_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, argument_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Instantiation}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Instantiation)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InstantiationOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getQualifierFieldBuilder();
          getArgumentFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (argumentBuilder_ == null) {
          argument_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          argumentBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (qualifierBuilder_ == null) {
          result.qualifier_ = qualifier_;
        } else {
          result.qualifier_ = qualifierBuilder_.build();
        }
        if (argumentBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            argument_ = java.util.Collections.unmodifiableList(argument_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.argument_ = argument_;
        } else {
          result.argument_ = argumentBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation.getDefaultInstance()) return this;
        if (other.hasQualifier()) {
          mergeQualifier(other.getQualifier());
        }
        if (argumentBuilder_ == null) {
          if (!other.argument_.isEmpty()) {
            if (argument_.isEmpty()) {
              argument_ = other.argument_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureArgumentIsMutable();
              argument_.addAll(other.argument_);
            }
            onChanged();
          }
        } else {
          if (!other.argument_.isEmpty()) {
            if (argumentBuilder_.isEmpty()) {
              argumentBuilder_.dispose();
              argumentBuilder_ = null;
              argument_ = other.argument_;
              bitField0_ = (bitField0_ & ~0x00000002);
              argumentBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getArgumentFieldBuilder() : null;
            } else {
              argumentBuilder_.addAllMessages(other.argument_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasQualifier()) {
          
          return false;
        }
        if (!getQualifier().isInitialized()) {
          
          return false;
        }
        for (int i = 0; i < getArgumentCount(); i++) {
          if (!getArgument(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Instantiation) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> qualifierBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public boolean hasQualifier() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getQualifier() {
        if (qualifierBuilder_ == null) {
          return qualifier_;
        } else {
          return qualifierBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder setQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          qualifier_ = value;
          onChanged();
        } else {
          qualifierBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder setQualifier(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (qualifierBuilder_ == null) {
          qualifier_ = builderForValue.build();
          onChanged();
        } else {
          qualifierBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder mergeQualifier(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (qualifierBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              qualifier_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            qualifier_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(qualifier_).mergeFrom(value).buildPartial();
          } else {
            qualifier_ = value;
          }
          onChanged();
        } else {
          qualifierBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public Builder clearQualifier() {
        if (qualifierBuilder_ == null) {
          qualifier_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          qualifierBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getQualifierBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getQualifierFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getQualifierOrBuilder() {
        if (qualifierBuilder_ != null) {
          return qualifierBuilder_.getMessageOrBuilder();
        } else {
          return qualifier_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression qualifier = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getQualifierFieldBuilder() {
        if (qualifierBuilder_ == null) {
          qualifierBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getQualifier(),
                  getParentForChildren(),
                  isClean());
          qualifier_ = null;
        }
        return qualifierBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> argument_ =
        java.util.Collections.emptyList();
      private void ensureArgumentIsMutable() {
        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
          argument_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>(argument_);
          bitField0_ |= 0x00000002;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> argumentBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getArgumentList() {
        if (argumentBuilder_ == null) {
          return java.util.Collections.unmodifiableList(argument_);
        } else {
          return argumentBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public int getArgumentCount() {
        if (argumentBuilder_ == null) {
          return argument_.size();
        } else {
          return argumentBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getArgument(int index) {
        if (argumentBuilder_ == null) {
          return argument_.get(index);
        } else {
          return argumentBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder setArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (argumentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureArgumentIsMutable();
          argument_.set(index, value);
          onChanged();
        } else {
          argumentBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder setArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.set(index, builderForValue.build());
          onChanged();
        } else {
          argumentBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (argumentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureArgumentIsMutable();
          argument_.add(value);
          onChanged();
        } else {
          argumentBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (argumentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureArgumentIsMutable();
          argument_.add(index, value);
          onChanged();
        } else {
          argumentBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.add(builderForValue.build());
          onChanged();
        } else {
          argumentBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addArgument(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.add(index, builderForValue.build());
          onChanged();
        } else {
          argumentBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder addAllArgument(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> values) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, argument_);
          onChanged();
        } else {
          argumentBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder clearArgument() {
        if (argumentBuilder_ == null) {
          argument_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          argumentBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public Builder removeArgument(int index) {
        if (argumentBuilder_ == null) {
          ensureArgumentIsMutable();
          argument_.remove(index);
          onChanged();
        } else {
          argumentBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getArgumentBuilder(
          int index) {
        return getArgumentFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getArgumentOrBuilder(
          int index) {
        if (argumentBuilder_ == null) {
          return argument_.get(index);  } else {
          return argumentBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
           getArgumentOrBuilderList() {
        if (argumentBuilder_ != null) {
          return argumentBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(argument_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addArgumentBuilder() {
        return getArgumentFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addArgumentBuilder(
          int index) {
        return getArgumentFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression argument = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder> 
           getArgumentBuilderList() {
        return getArgumentFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getArgumentFieldBuilder() {
        if (argumentBuilder_ == null) {
          argumentBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  argument_,
                  ((bitField0_ & 0x00000002) == 0x00000002),
                  getParentForChildren(),
                  isClean());
          argument_ = null;
        }
        return argumentBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Instantiation)
    }

    static {
      defaultInstance = new Instantiation(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Instantiation)
  }

  public interface StatementOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Statement)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 fileId = 1;</code>
     */
    boolean hasFileId();
    /**
     * <code>optional int32 fileId = 1;</code>
     */
    int getFileId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    boolean hasLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder();

    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    boolean hasSynthetic();
    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    boolean getSynthetic();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
     */
    boolean hasReturnStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return getReturnStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder getReturnStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
     */
    boolean hasThrowStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw getThrowStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder getThrowStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
     */
    boolean hasBreakStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break getBreakStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder getBreakStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
     */
    boolean hasContinueStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue getContinueStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder getContinueStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
     */
    boolean hasDebugger();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger getDebugger();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder getDebuggerOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
     */
    boolean hasExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement getExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder getExpressionOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
     */
    boolean hasVars();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars getVars();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder getVarsOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
     */
    boolean hasBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block getBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder getBlockOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
     */
    boolean hasGlobalBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getGlobalBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getGlobalBlockOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
     */
    boolean hasLabel();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label getLabel();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder getLabelOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
     */
    boolean hasIfStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If getIfStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder getIfStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
     */
    boolean hasSwitchStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch getSwitchStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder getSwitchStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
     */
    boolean hasWhileStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While getWhileStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder getWhileStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
     */
    boolean hasDoWhileStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile getDoWhileStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder getDoWhileStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
     */
    boolean hasForStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For getForStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder getForStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
     */
    boolean hasForInStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn getForInStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder getForInStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
     */
    boolean hasTryStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try getTryStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder getTryStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
     */
    boolean hasEmpty();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty getEmpty();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder getEmptyOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Statement}
   */
  public static final class Statement extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Statement)
      StatementOrBuilder {
    // Use Statement.newBuilder() to construct.
    private Statement(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Statement(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Statement defaultInstance;
    public static Statement getDefaultInstance() {
      return defaultInstance;
    }

    public Statement getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Statement(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              fileId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = location_.toBuilder();
              }
              location_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(location_);
                location_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              synthetic_ = input.readBool();
              break;
            }
            case 170: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder subBuilder = null;
              if (statementCase_ == 21) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 21;
              break;
            }
            case 178: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder subBuilder = null;
              if (statementCase_ == 22) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 22;
              break;
            }
            case 186: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder subBuilder = null;
              if (statementCase_ == 23) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 23;
              break;
            }
            case 194: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder subBuilder = null;
              if (statementCase_ == 24) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 24;
              break;
            }
            case 202: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder subBuilder = null;
              if (statementCase_ == 25) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 25;
              break;
            }
            case 210: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder subBuilder = null;
              if (statementCase_ == 26) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 26;
              break;
            }
            case 218: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder subBuilder = null;
              if (statementCase_ == 27) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 27;
              break;
            }
            case 226: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder subBuilder = null;
              if (statementCase_ == 28) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 28;
              break;
            }
            case 234: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder subBuilder = null;
              if (statementCase_ == 29) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 29;
              break;
            }
            case 242: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder subBuilder = null;
              if (statementCase_ == 30) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 30;
              break;
            }
            case 250: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder subBuilder = null;
              if (statementCase_ == 31) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 31;
              break;
            }
            case 258: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder subBuilder = null;
              if (statementCase_ == 32) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 32;
              break;
            }
            case 266: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder subBuilder = null;
              if (statementCase_ == 33) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 33;
              break;
            }
            case 274: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder subBuilder = null;
              if (statementCase_ == 34) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 34;
              break;
            }
            case 282: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder subBuilder = null;
              if (statementCase_ == 35) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 35;
              break;
            }
            case 290: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder subBuilder = null;
              if (statementCase_ == 36) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 36;
              break;
            }
            case 298: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder subBuilder = null;
              if (statementCase_ == 37) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 37;
              break;
            }
            case 306: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder subBuilder = null;
              if (statementCase_ == 38) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_).toBuilder();
              }
              statement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_);
                statement_ = subBuilder.buildPartial();
              }
              statementCase_ = 38;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Statement> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Statement>() {
      public Statement parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Statement(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Statement> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    private int statementCase_ = 0;
    private java.lang.Object statement_;
    public enum StatementCase
        implements org.jetbrains.kotlin.protobuf.Internal.EnumLite {
      RETURN_STATEMENT(21),
      THROW_STATEMENT(22),
      BREAK_STATEMENT(23),
      CONTINUE_STATEMENT(24),
      DEBUGGER(25),
      EXPRESSION(26),
      VARS(27),
      BLOCK(28),
      GLOBAL_BLOCK(29),
      LABEL(30),
      IF_STATEMENT(31),
      SWITCH_STATEMENT(32),
      WHILE_STATEMENT(33),
      DO_WHILE_STATEMENT(34),
      FOR_STATEMENT(35),
      FOR_IN_STATEMENT(36),
      TRY_STATEMENT(37),
      EMPTY(38),
      STATEMENT_NOT_SET(0);
      private int value = 0;
      private StatementCase(int value) {
        this.value = value;
      }
      public static StatementCase valueOf(int value) {
        switch (value) {
          case 21: return RETURN_STATEMENT;
          case 22: return THROW_STATEMENT;
          case 23: return BREAK_STATEMENT;
          case 24: return CONTINUE_STATEMENT;
          case 25: return DEBUGGER;
          case 26: return EXPRESSION;
          case 27: return VARS;
          case 28: return BLOCK;
          case 29: return GLOBAL_BLOCK;
          case 30: return LABEL;
          case 31: return IF_STATEMENT;
          case 32: return SWITCH_STATEMENT;
          case 33: return WHILE_STATEMENT;
          case 34: return DO_WHILE_STATEMENT;
          case 35: return FOR_STATEMENT;
          case 36: return FOR_IN_STATEMENT;
          case 37: return TRY_STATEMENT;
          case 38: return EMPTY;
          case 0: return STATEMENT_NOT_SET;
          default: throw new java.lang.IllegalArgumentException(
            "Value is undefined for this oneof enum.");
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public StatementCase
    getStatementCase() {
      return StatementCase.valueOf(
          statementCase_);
    }

    public static final int FILEID_FIELD_NUMBER = 1;
    private int fileId_;
    /**
     * <code>optional int32 fileId = 1;</code>
     */
    public boolean hasFileId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 fileId = 1;</code>
     */
    public int getFileId() {
      return fileId_;
    }

    public static final int LOCATION_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    public boolean hasLocation() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
      return location_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
      return location_;
    }

    public static final int SYNTHETIC_FIELD_NUMBER = 3;
    private boolean synthetic_;
    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    public boolean hasSynthetic() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional bool synthetic = 3 [default = false];</code>
     */
    public boolean getSynthetic() {
      return synthetic_;
    }

    public static final int RETURN_STATEMENT_FIELD_NUMBER = 21;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
     */
    public boolean hasReturnStatement() {
      return statementCase_ == 21;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return getReturnStatement() {
      if (statementCase_ == 21) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder getReturnStatementOrBuilder() {
      if (statementCase_ == 21) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
    }

    public static final int THROW_STATEMENT_FIELD_NUMBER = 22;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
     */
    public boolean hasThrowStatement() {
      return statementCase_ == 22;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw getThrowStatement() {
      if (statementCase_ == 22) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder getThrowStatementOrBuilder() {
      if (statementCase_ == 22) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
    }

    public static final int BREAK_STATEMENT_FIELD_NUMBER = 23;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
     */
    public boolean hasBreakStatement() {
      return statementCase_ == 23;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break getBreakStatement() {
      if (statementCase_ == 23) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder getBreakStatementOrBuilder() {
      if (statementCase_ == 23) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
    }

    public static final int CONTINUE_STATEMENT_FIELD_NUMBER = 24;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
     */
    public boolean hasContinueStatement() {
      return statementCase_ == 24;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue getContinueStatement() {
      if (statementCase_ == 24) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder getContinueStatementOrBuilder() {
      if (statementCase_ == 24) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
    }

    public static final int DEBUGGER_FIELD_NUMBER = 25;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
     */
    public boolean hasDebugger() {
      return statementCase_ == 25;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger getDebugger() {
      if (statementCase_ == 25) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder getDebuggerOrBuilder() {
      if (statementCase_ == 25) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
    }

    public static final int EXPRESSION_FIELD_NUMBER = 26;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
     */
    public boolean hasExpression() {
      return statementCase_ == 26;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement getExpression() {
      if (statementCase_ == 26) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder getExpressionOrBuilder() {
      if (statementCase_ == 26) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
    }

    public static final int VARS_FIELD_NUMBER = 27;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
     */
    public boolean hasVars() {
      return statementCase_ == 27;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars getVars() {
      if (statementCase_ == 27) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder getVarsOrBuilder() {
      if (statementCase_ == 27) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
    }

    public static final int BLOCK_FIELD_NUMBER = 28;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
     */
    public boolean hasBlock() {
      return statementCase_ == 28;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block getBlock() {
      if (statementCase_ == 28) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder getBlockOrBuilder() {
      if (statementCase_ == 28) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
    }

    public static final int GLOBAL_BLOCK_FIELD_NUMBER = 29;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
     */
    public boolean hasGlobalBlock() {
      return statementCase_ == 29;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getGlobalBlock() {
      if (statementCase_ == 29) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getGlobalBlockOrBuilder() {
      if (statementCase_ == 29) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
    }

    public static final int LABEL_FIELD_NUMBER = 30;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
     */
    public boolean hasLabel() {
      return statementCase_ == 30;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label getLabel() {
      if (statementCase_ == 30) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder getLabelOrBuilder() {
      if (statementCase_ == 30) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
    }

    public static final int IF_STATEMENT_FIELD_NUMBER = 31;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
     */
    public boolean hasIfStatement() {
      return statementCase_ == 31;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If getIfStatement() {
      if (statementCase_ == 31) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder getIfStatementOrBuilder() {
      if (statementCase_ == 31) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
    }

    public static final int SWITCH_STATEMENT_FIELD_NUMBER = 32;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
     */
    public boolean hasSwitchStatement() {
      return statementCase_ == 32;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch getSwitchStatement() {
      if (statementCase_ == 32) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder getSwitchStatementOrBuilder() {
      if (statementCase_ == 32) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
    }

    public static final int WHILE_STATEMENT_FIELD_NUMBER = 33;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
     */
    public boolean hasWhileStatement() {
      return statementCase_ == 33;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While getWhileStatement() {
      if (statementCase_ == 33) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder getWhileStatementOrBuilder() {
      if (statementCase_ == 33) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
    }

    public static final int DO_WHILE_STATEMENT_FIELD_NUMBER = 34;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
     */
    public boolean hasDoWhileStatement() {
      return statementCase_ == 34;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile getDoWhileStatement() {
      if (statementCase_ == 34) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder getDoWhileStatementOrBuilder() {
      if (statementCase_ == 34) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
    }

    public static final int FOR_STATEMENT_FIELD_NUMBER = 35;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
     */
    public boolean hasForStatement() {
      return statementCase_ == 35;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For getForStatement() {
      if (statementCase_ == 35) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder getForStatementOrBuilder() {
      if (statementCase_ == 35) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
    }

    public static final int FOR_IN_STATEMENT_FIELD_NUMBER = 36;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
     */
    public boolean hasForInStatement() {
      return statementCase_ == 36;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn getForInStatement() {
      if (statementCase_ == 36) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder getForInStatementOrBuilder() {
      if (statementCase_ == 36) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
    }

    public static final int TRY_STATEMENT_FIELD_NUMBER = 37;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
     */
    public boolean hasTryStatement() {
      return statementCase_ == 37;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try getTryStatement() {
      if (statementCase_ == 37) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder getTryStatementOrBuilder() {
      if (statementCase_ == 37) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
    }

    public static final int EMPTY_FIELD_NUMBER = 38;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
     */
    public boolean hasEmpty() {
      return statementCase_ == 38;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty getEmpty() {
      if (statementCase_ == 38) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder getEmptyOrBuilder() {
      if (statementCase_ == 38) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
    }

    private void initFields() {
      fileId_ = 0;
      location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      synthetic_ = false;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (hasLocation()) {
        if (!getLocation().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasReturnStatement()) {
        if (!getReturnStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasThrowStatement()) {
        if (!getThrowStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasExpression()) {
        if (!getExpression().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasVars()) {
        if (!getVars().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasBlock()) {
        if (!getBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasGlobalBlock()) {
        if (!getGlobalBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasLabel()) {
        if (!getLabel().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasIfStatement()) {
        if (!getIfStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasSwitchStatement()) {
        if (!getSwitchStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasWhileStatement()) {
        if (!getWhileStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasDoWhileStatement()) {
        if (!getDoWhileStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasForStatement()) {
        if (!getForStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasForInStatement()) {
        if (!getForInStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasTryStatement()) {
        if (!getTryStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, fileId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, location_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeBool(3, synthetic_);
      }
      if (statementCase_ == 21) {
        output.writeMessage(21, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_);
      }
      if (statementCase_ == 22) {
        output.writeMessage(22, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_);
      }
      if (statementCase_ == 23) {
        output.writeMessage(23, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_);
      }
      if (statementCase_ == 24) {
        output.writeMessage(24, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_);
      }
      if (statementCase_ == 25) {
        output.writeMessage(25, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_);
      }
      if (statementCase_ == 26) {
        output.writeMessage(26, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_);
      }
      if (statementCase_ == 27) {
        output.writeMessage(27, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_);
      }
      if (statementCase_ == 28) {
        output.writeMessage(28, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_);
      }
      if (statementCase_ == 29) {
        output.writeMessage(29, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_);
      }
      if (statementCase_ == 30) {
        output.writeMessage(30, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_);
      }
      if (statementCase_ == 31) {
        output.writeMessage(31, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_);
      }
      if (statementCase_ == 32) {
        output.writeMessage(32, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_);
      }
      if (statementCase_ == 33) {
        output.writeMessage(33, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_);
      }
      if (statementCase_ == 34) {
        output.writeMessage(34, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_);
      }
      if (statementCase_ == 35) {
        output.writeMessage(35, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_);
      }
      if (statementCase_ == 36) {
        output.writeMessage(36, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_);
      }
      if (statementCase_ == 37) {
        output.writeMessage(37, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_);
      }
      if (statementCase_ == 38) {
        output.writeMessage(38, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, fileId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, location_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(3, synthetic_);
      }
      if (statementCase_ == 21) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(21, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_);
      }
      if (statementCase_ == 22) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(22, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_);
      }
      if (statementCase_ == 23) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(23, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_);
      }
      if (statementCase_ == 24) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(24, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_);
      }
      if (statementCase_ == 25) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(25, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_);
      }
      if (statementCase_ == 26) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(26, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_);
      }
      if (statementCase_ == 27) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(27, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_);
      }
      if (statementCase_ == 28) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(28, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_);
      }
      if (statementCase_ == 29) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(29, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_);
      }
      if (statementCase_ == 30) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(30, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_);
      }
      if (statementCase_ == 31) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(31, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_);
      }
      if (statementCase_ == 32) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(32, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_);
      }
      if (statementCase_ == 33) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(33, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_);
      }
      if (statementCase_ == 34) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(34, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_);
      }
      if (statementCase_ == 35) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(35, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_);
      }
      if (statementCase_ == 36) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(36, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_);
      }
      if (statementCase_ == 37) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(37, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_);
      }
      if (statementCase_ == 38) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(38, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Statement}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Statement)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getLocationFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        fileId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        synthetic_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        statementCase_ = 0;
        statement_ = null;
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.fileId_ = fileId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (locationBuilder_ == null) {
          result.location_ = location_;
        } else {
          result.location_ = locationBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.synthetic_ = synthetic_;
        if (statementCase_ == 21) {
          if (returnStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = returnStatementBuilder_.build();
          }
        }
        if (statementCase_ == 22) {
          if (throwStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = throwStatementBuilder_.build();
          }
        }
        if (statementCase_ == 23) {
          if (breakStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = breakStatementBuilder_.build();
          }
        }
        if (statementCase_ == 24) {
          if (continueStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = continueStatementBuilder_.build();
          }
        }
        if (statementCase_ == 25) {
          if (debuggerBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = debuggerBuilder_.build();
          }
        }
        if (statementCase_ == 26) {
          if (expressionBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = expressionBuilder_.build();
          }
        }
        if (statementCase_ == 27) {
          if (varsBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = varsBuilder_.build();
          }
        }
        if (statementCase_ == 28) {
          if (blockBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = blockBuilder_.build();
          }
        }
        if (statementCase_ == 29) {
          if (globalBlockBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = globalBlockBuilder_.build();
          }
        }
        if (statementCase_ == 30) {
          if (labelBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = labelBuilder_.build();
          }
        }
        if (statementCase_ == 31) {
          if (ifStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = ifStatementBuilder_.build();
          }
        }
        if (statementCase_ == 32) {
          if (switchStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = switchStatementBuilder_.build();
          }
        }
        if (statementCase_ == 33) {
          if (whileStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = whileStatementBuilder_.build();
          }
        }
        if (statementCase_ == 34) {
          if (doWhileStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = doWhileStatementBuilder_.build();
          }
        }
        if (statementCase_ == 35) {
          if (forStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = forStatementBuilder_.build();
          }
        }
        if (statementCase_ == 36) {
          if (forInStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = forInStatementBuilder_.build();
          }
        }
        if (statementCase_ == 37) {
          if (tryStatementBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = tryStatementBuilder_.build();
          }
        }
        if (statementCase_ == 38) {
          if (emptyBuilder_ == null) {
            result.statement_ = statement_;
          } else {
            result.statement_ = emptyBuilder_.build();
          }
        }
        result.bitField0_ = to_bitField0_;
        result.statementCase_ = statementCase_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) return this;
        if (other.hasFileId()) {
          setFileId(other.getFileId());
        }
        if (other.hasLocation()) {
          mergeLocation(other.getLocation());
        }
        if (other.hasSynthetic()) {
          setSynthetic(other.getSynthetic());
        }
        switch (other.getStatementCase()) {
          case RETURN_STATEMENT: {
            mergeReturnStatement(other.getReturnStatement());
            break;
          }
          case THROW_STATEMENT: {
            mergeThrowStatement(other.getThrowStatement());
            break;
          }
          case BREAK_STATEMENT: {
            mergeBreakStatement(other.getBreakStatement());
            break;
          }
          case CONTINUE_STATEMENT: {
            mergeContinueStatement(other.getContinueStatement());
            break;
          }
          case DEBUGGER: {
            mergeDebugger(other.getDebugger());
            break;
          }
          case EXPRESSION: {
            mergeExpression(other.getExpression());
            break;
          }
          case VARS: {
            mergeVars(other.getVars());
            break;
          }
          case BLOCK: {
            mergeBlock(other.getBlock());
            break;
          }
          case GLOBAL_BLOCK: {
            mergeGlobalBlock(other.getGlobalBlock());
            break;
          }
          case LABEL: {
            mergeLabel(other.getLabel());
            break;
          }
          case IF_STATEMENT: {
            mergeIfStatement(other.getIfStatement());
            break;
          }
          case SWITCH_STATEMENT: {
            mergeSwitchStatement(other.getSwitchStatement());
            break;
          }
          case WHILE_STATEMENT: {
            mergeWhileStatement(other.getWhileStatement());
            break;
          }
          case DO_WHILE_STATEMENT: {
            mergeDoWhileStatement(other.getDoWhileStatement());
            break;
          }
          case FOR_STATEMENT: {
            mergeForStatement(other.getForStatement());
            break;
          }
          case FOR_IN_STATEMENT: {
            mergeForInStatement(other.getForInStatement());
            break;
          }
          case TRY_STATEMENT: {
            mergeTryStatement(other.getTryStatement());
            break;
          }
          case EMPTY: {
            mergeEmpty(other.getEmpty());
            break;
          }
          case STATEMENT_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (hasLocation()) {
          if (!getLocation().isInitialized()) {
            
            return false;
          }
        }
        if (hasReturnStatement()) {
          if (!getReturnStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasThrowStatement()) {
          if (!getThrowStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasExpression()) {
          if (!getExpression().isInitialized()) {
            
            return false;
          }
        }
        if (hasVars()) {
          if (!getVars().isInitialized()) {
            
            return false;
          }
        }
        if (hasBlock()) {
          if (!getBlock().isInitialized()) {
            
            return false;
          }
        }
        if (hasGlobalBlock()) {
          if (!getGlobalBlock().isInitialized()) {
            
            return false;
          }
        }
        if (hasLabel()) {
          if (!getLabel().isInitialized()) {
            
            return false;
          }
        }
        if (hasIfStatement()) {
          if (!getIfStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasSwitchStatement()) {
          if (!getSwitchStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasWhileStatement()) {
          if (!getWhileStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasDoWhileStatement()) {
          if (!getDoWhileStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasForStatement()) {
          if (!getForStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasForInStatement()) {
          if (!getForInStatement().isInitialized()) {
            
            return false;
          }
        }
        if (hasTryStatement()) {
          if (!getTryStatement().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int statementCase_ = 0;
      private java.lang.Object statement_;
      public StatementCase
          getStatementCase() {
        return StatementCase.valueOf(
            statementCase_);
      }

      public Builder clearStatement() {
        statementCase_ = 0;
        statement_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private int fileId_ ;
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public boolean hasFileId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public int getFileId() {
        return fileId_;
      }
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public Builder setFileId(int value) {
        bitField0_ |= 0x00000001;
        fileId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 fileId = 1;</code>
       */
      public Builder clearFileId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        fileId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> locationBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public boolean hasLocation() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
        if (locationBuilder_ == null) {
          return location_;
        } else {
          return locationBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder setLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          location_ = value;
          onChanged();
        } else {
          locationBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder setLocation(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder builderForValue) {
        if (locationBuilder_ == null) {
          location_ = builderForValue.build();
          onChanged();
        } else {
          locationBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder mergeLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              location_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance()) {
            location_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.newBuilder(location_).mergeFrom(value).buildPartial();
          } else {
            location_ = value;
          }
          onChanged();
        } else {
          locationBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public Builder clearLocation() {
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
          onChanged();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder getLocationBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getLocationFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
        if (locationBuilder_ != null) {
          return locationBuilder_.getMessageOrBuilder();
        } else {
          return location_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> 
          getLocationFieldBuilder() {
        if (locationBuilder_ == null) {
          locationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder>(
                  getLocation(),
                  getParentForChildren(),
                  isClean());
          location_ = null;
        }
        return locationBuilder_;
      }

      private boolean synthetic_ ;
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public boolean hasSynthetic() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public boolean getSynthetic() {
        return synthetic_;
      }
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public Builder setSynthetic(boolean value) {
        bitField0_ |= 0x00000004;
        synthetic_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool synthetic = 3 [default = false];</code>
       */
      public Builder clearSynthetic() {
        bitField0_ = (bitField0_ & ~0x00000004);
        synthetic_ = false;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder> returnStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public boolean hasReturnStatement() {
        return statementCase_ == 21;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return getReturnStatement() {
        if (returnStatementBuilder_ == null) {
          if (statementCase_ == 21) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
        } else {
          if (statementCase_ == 21) {
            return returnStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public Builder setReturnStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return value) {
        if (returnStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          returnStatementBuilder_.setMessage(value);
        }
        statementCase_ = 21;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public Builder setReturnStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder builderForValue) {
        if (returnStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          returnStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 21;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public Builder mergeReturnStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return value) {
        if (returnStatementBuilder_ == null) {
          if (statementCase_ == 21 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 21) {
            returnStatementBuilder_.mergeFrom(value);
          }
          returnStatementBuilder_.setMessage(value);
        }
        statementCase_ = 21;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public Builder clearReturnStatement() {
        if (returnStatementBuilder_ == null) {
          if (statementCase_ == 21) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 21) {
            statementCase_ = 0;
            statement_ = null;
          }
          returnStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder getReturnStatementBuilder() {
        return getReturnStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder getReturnStatementOrBuilder() {
        if ((statementCase_ == 21) && (returnStatementBuilder_ != null)) {
          return returnStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 21) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Return return_statement = 21;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder> 
          getReturnStatementFieldBuilder() {
        if (returnStatementBuilder_ == null) {
          if (!(statementCase_ == 21)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
          }
          returnStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 21;
        return returnStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder> throwStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public boolean hasThrowStatement() {
        return statementCase_ == 22;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw getThrowStatement() {
        if (throwStatementBuilder_ == null) {
          if (statementCase_ == 22) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
        } else {
          if (statementCase_ == 22) {
            return throwStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public Builder setThrowStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw value) {
        if (throwStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          throwStatementBuilder_.setMessage(value);
        }
        statementCase_ = 22;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public Builder setThrowStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder builderForValue) {
        if (throwStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          throwStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 22;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public Builder mergeThrowStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw value) {
        if (throwStatementBuilder_ == null) {
          if (statementCase_ == 22 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 22) {
            throwStatementBuilder_.mergeFrom(value);
          }
          throwStatementBuilder_.setMessage(value);
        }
        statementCase_ = 22;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public Builder clearThrowStatement() {
        if (throwStatementBuilder_ == null) {
          if (statementCase_ == 22) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 22) {
            statementCase_ = 0;
            statement_ = null;
          }
          throwStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder getThrowStatementBuilder() {
        return getThrowStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder getThrowStatementOrBuilder() {
        if ((statementCase_ == 22) && (throwStatementBuilder_ != null)) {
          return throwStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 22) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Throw throw_statement = 22;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder> 
          getThrowStatementFieldBuilder() {
        if (throwStatementBuilder_ == null) {
          if (!(statementCase_ == 22)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
          }
          throwStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 22;
        return throwStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder> breakStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public boolean hasBreakStatement() {
        return statementCase_ == 23;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break getBreakStatement() {
        if (breakStatementBuilder_ == null) {
          if (statementCase_ == 23) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
        } else {
          if (statementCase_ == 23) {
            return breakStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public Builder setBreakStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break value) {
        if (breakStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          breakStatementBuilder_.setMessage(value);
        }
        statementCase_ = 23;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public Builder setBreakStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder builderForValue) {
        if (breakStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          breakStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 23;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public Builder mergeBreakStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break value) {
        if (breakStatementBuilder_ == null) {
          if (statementCase_ == 23 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 23) {
            breakStatementBuilder_.mergeFrom(value);
          }
          breakStatementBuilder_.setMessage(value);
        }
        statementCase_ = 23;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public Builder clearBreakStatement() {
        if (breakStatementBuilder_ == null) {
          if (statementCase_ == 23) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 23) {
            statementCase_ = 0;
            statement_ = null;
          }
          breakStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder getBreakStatementBuilder() {
        return getBreakStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder getBreakStatementOrBuilder() {
        if ((statementCase_ == 23) && (breakStatementBuilder_ != null)) {
          return breakStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 23) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Break break_statement = 23;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder> 
          getBreakStatementFieldBuilder() {
        if (breakStatementBuilder_ == null) {
          if (!(statementCase_ == 23)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
          }
          breakStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 23;
        return breakStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder> continueStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public boolean hasContinueStatement() {
        return statementCase_ == 24;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue getContinueStatement() {
        if (continueStatementBuilder_ == null) {
          if (statementCase_ == 24) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
        } else {
          if (statementCase_ == 24) {
            return continueStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public Builder setContinueStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue value) {
        if (continueStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          continueStatementBuilder_.setMessage(value);
        }
        statementCase_ = 24;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public Builder setContinueStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder builderForValue) {
        if (continueStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          continueStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 24;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public Builder mergeContinueStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue value) {
        if (continueStatementBuilder_ == null) {
          if (statementCase_ == 24 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 24) {
            continueStatementBuilder_.mergeFrom(value);
          }
          continueStatementBuilder_.setMessage(value);
        }
        statementCase_ = 24;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public Builder clearContinueStatement() {
        if (continueStatementBuilder_ == null) {
          if (statementCase_ == 24) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 24) {
            statementCase_ = 0;
            statement_ = null;
          }
          continueStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder getContinueStatementBuilder() {
        return getContinueStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder getContinueStatementOrBuilder() {
        if ((statementCase_ == 24) && (continueStatementBuilder_ != null)) {
          return continueStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 24) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Continue continue_statement = 24;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder> 
          getContinueStatementFieldBuilder() {
        if (continueStatementBuilder_ == null) {
          if (!(statementCase_ == 24)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
          }
          continueStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 24;
        return continueStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder> debuggerBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public boolean hasDebugger() {
        return statementCase_ == 25;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger getDebugger() {
        if (debuggerBuilder_ == null) {
          if (statementCase_ == 25) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
        } else {
          if (statementCase_ == 25) {
            return debuggerBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public Builder setDebugger(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger value) {
        if (debuggerBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          debuggerBuilder_.setMessage(value);
        }
        statementCase_ = 25;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public Builder setDebugger(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder builderForValue) {
        if (debuggerBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          debuggerBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 25;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public Builder mergeDebugger(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger value) {
        if (debuggerBuilder_ == null) {
          if (statementCase_ == 25 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 25) {
            debuggerBuilder_.mergeFrom(value);
          }
          debuggerBuilder_.setMessage(value);
        }
        statementCase_ = 25;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public Builder clearDebugger() {
        if (debuggerBuilder_ == null) {
          if (statementCase_ == 25) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 25) {
            statementCase_ = 0;
            statement_ = null;
          }
          debuggerBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder getDebuggerBuilder() {
        return getDebuggerFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder getDebuggerOrBuilder() {
        if ((statementCase_ == 25) && (debuggerBuilder_ != null)) {
          return debuggerBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 25) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Debugger debugger = 25;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder> 
          getDebuggerFieldBuilder() {
        if (debuggerBuilder_ == null) {
          if (!(statementCase_ == 25)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
          }
          debuggerBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 25;
        return debuggerBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder> expressionBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public boolean hasExpression() {
        return statementCase_ == 26;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement getExpression() {
        if (expressionBuilder_ == null) {
          if (statementCase_ == 26) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
        } else {
          if (statementCase_ == 26) {
            return expressionBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        statementCase_ = 26;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 26;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement value) {
        if (expressionBuilder_ == null) {
          if (statementCase_ == 26 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 26) {
            expressionBuilder_.mergeFrom(value);
          }
          expressionBuilder_.setMessage(value);
        }
        statementCase_ = 26;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          if (statementCase_ == 26) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 26) {
            statementCase_ = 0;
            statement_ = null;
          }
          expressionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder getExpressionBuilder() {
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder getExpressionOrBuilder() {
        if ((statementCase_ == 26) && (expressionBuilder_ != null)) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 26) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement expression = 26;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          if (!(statementCase_ == 26)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
          }
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 26;
        return expressionBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder> varsBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public boolean hasVars() {
        return statementCase_ == 27;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars getVars() {
        if (varsBuilder_ == null) {
          if (statementCase_ == 27) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
        } else {
          if (statementCase_ == 27) {
            return varsBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public Builder setVars(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars value) {
        if (varsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          varsBuilder_.setMessage(value);
        }
        statementCase_ = 27;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public Builder setVars(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder builderForValue) {
        if (varsBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          varsBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 27;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public Builder mergeVars(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars value) {
        if (varsBuilder_ == null) {
          if (statementCase_ == 27 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 27) {
            varsBuilder_.mergeFrom(value);
          }
          varsBuilder_.setMessage(value);
        }
        statementCase_ = 27;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public Builder clearVars() {
        if (varsBuilder_ == null) {
          if (statementCase_ == 27) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 27) {
            statementCase_ = 0;
            statement_ = null;
          }
          varsBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder getVarsBuilder() {
        return getVarsFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder getVarsOrBuilder() {
        if ((statementCase_ == 27) && (varsBuilder_ != null)) {
          return varsBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 27) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Vars vars = 27;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder> 
          getVarsFieldBuilder() {
        if (varsBuilder_ == null) {
          if (!(statementCase_ == 27)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
          }
          varsBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 27;
        return varsBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder> blockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public boolean hasBlock() {
        return statementCase_ == 28;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block getBlock() {
        if (blockBuilder_ == null) {
          if (statementCase_ == 28) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
        } else {
          if (statementCase_ == 28) {
            return blockBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public Builder setBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block value) {
        if (blockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          blockBuilder_.setMessage(value);
        }
        statementCase_ = 28;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public Builder setBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder builderForValue) {
        if (blockBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          blockBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 28;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public Builder mergeBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block value) {
        if (blockBuilder_ == null) {
          if (statementCase_ == 28 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 28) {
            blockBuilder_.mergeFrom(value);
          }
          blockBuilder_.setMessage(value);
        }
        statementCase_ = 28;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public Builder clearBlock() {
        if (blockBuilder_ == null) {
          if (statementCase_ == 28) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 28) {
            statementCase_ = 0;
            statement_ = null;
          }
          blockBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder getBlockBuilder() {
        return getBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder getBlockOrBuilder() {
        if ((statementCase_ == 28) && (blockBuilder_ != null)) {
          return blockBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 28) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Block block = 28;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder> 
          getBlockFieldBuilder() {
        if (blockBuilder_ == null) {
          if (!(statementCase_ == 28)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
          }
          blockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 28;
        return blockBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> globalBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public boolean hasGlobalBlock() {
        return statementCase_ == 29;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getGlobalBlock() {
        if (globalBlockBuilder_ == null) {
          if (statementCase_ == 29) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        } else {
          if (statementCase_ == 29) {
            return globalBlockBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public Builder setGlobalBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (globalBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          globalBlockBuilder_.setMessage(value);
        }
        statementCase_ = 29;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public Builder setGlobalBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder builderForValue) {
        if (globalBlockBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          globalBlockBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 29;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public Builder mergeGlobalBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (globalBlockBuilder_ == null) {
          if (statementCase_ == 29 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 29) {
            globalBlockBuilder_.mergeFrom(value);
          }
          globalBlockBuilder_.setMessage(value);
        }
        statementCase_ = 29;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public Builder clearGlobalBlock() {
        if (globalBlockBuilder_ == null) {
          if (statementCase_ == 29) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 29) {
            statementCase_ = 0;
            statement_ = null;
          }
          globalBlockBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder getGlobalBlockBuilder() {
        return getGlobalBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getGlobalBlockOrBuilder() {
        if ((statementCase_ == 29) && (globalBlockBuilder_ != null)) {
          return globalBlockBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 29) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock global_block = 29;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> 
          getGlobalBlockFieldBuilder() {
        if (globalBlockBuilder_ == null) {
          if (!(statementCase_ == 29)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
          }
          globalBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 29;
        return globalBlockBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder> labelBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public boolean hasLabel() {
        return statementCase_ == 30;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label getLabel() {
        if (labelBuilder_ == null) {
          if (statementCase_ == 30) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
        } else {
          if (statementCase_ == 30) {
            return labelBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public Builder setLabel(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label value) {
        if (labelBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          labelBuilder_.setMessage(value);
        }
        statementCase_ = 30;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public Builder setLabel(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder builderForValue) {
        if (labelBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          labelBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 30;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public Builder mergeLabel(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label value) {
        if (labelBuilder_ == null) {
          if (statementCase_ == 30 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 30) {
            labelBuilder_.mergeFrom(value);
          }
          labelBuilder_.setMessage(value);
        }
        statementCase_ = 30;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public Builder clearLabel() {
        if (labelBuilder_ == null) {
          if (statementCase_ == 30) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 30) {
            statementCase_ = 0;
            statement_ = null;
          }
          labelBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder getLabelBuilder() {
        return getLabelFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder getLabelOrBuilder() {
        if ((statementCase_ == 30) && (labelBuilder_ != null)) {
          return labelBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 30) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Label label = 30;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder> 
          getLabelFieldBuilder() {
        if (labelBuilder_ == null) {
          if (!(statementCase_ == 30)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
          }
          labelBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 30;
        return labelBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder> ifStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public boolean hasIfStatement() {
        return statementCase_ == 31;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If getIfStatement() {
        if (ifStatementBuilder_ == null) {
          if (statementCase_ == 31) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
        } else {
          if (statementCase_ == 31) {
            return ifStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public Builder setIfStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If value) {
        if (ifStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          ifStatementBuilder_.setMessage(value);
        }
        statementCase_ = 31;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public Builder setIfStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder builderForValue) {
        if (ifStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          ifStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 31;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public Builder mergeIfStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If value) {
        if (ifStatementBuilder_ == null) {
          if (statementCase_ == 31 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 31) {
            ifStatementBuilder_.mergeFrom(value);
          }
          ifStatementBuilder_.setMessage(value);
        }
        statementCase_ = 31;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public Builder clearIfStatement() {
        if (ifStatementBuilder_ == null) {
          if (statementCase_ == 31) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 31) {
            statementCase_ = 0;
            statement_ = null;
          }
          ifStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder getIfStatementBuilder() {
        return getIfStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder getIfStatementOrBuilder() {
        if ((statementCase_ == 31) && (ifStatementBuilder_ != null)) {
          return ifStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 31) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.If if_statement = 31;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder> 
          getIfStatementFieldBuilder() {
        if (ifStatementBuilder_ == null) {
          if (!(statementCase_ == 31)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
          }
          ifStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 31;
        return ifStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder> switchStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public boolean hasSwitchStatement() {
        return statementCase_ == 32;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch getSwitchStatement() {
        if (switchStatementBuilder_ == null) {
          if (statementCase_ == 32) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
        } else {
          if (statementCase_ == 32) {
            return switchStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public Builder setSwitchStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch value) {
        if (switchStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          switchStatementBuilder_.setMessage(value);
        }
        statementCase_ = 32;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public Builder setSwitchStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder builderForValue) {
        if (switchStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          switchStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 32;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public Builder mergeSwitchStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch value) {
        if (switchStatementBuilder_ == null) {
          if (statementCase_ == 32 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 32) {
            switchStatementBuilder_.mergeFrom(value);
          }
          switchStatementBuilder_.setMessage(value);
        }
        statementCase_ = 32;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public Builder clearSwitchStatement() {
        if (switchStatementBuilder_ == null) {
          if (statementCase_ == 32) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 32) {
            statementCase_ = 0;
            statement_ = null;
          }
          switchStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder getSwitchStatementBuilder() {
        return getSwitchStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder getSwitchStatementOrBuilder() {
        if ((statementCase_ == 32) && (switchStatementBuilder_ != null)) {
          return switchStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 32) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Switch switch_statement = 32;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder> 
          getSwitchStatementFieldBuilder() {
        if (switchStatementBuilder_ == null) {
          if (!(statementCase_ == 32)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
          }
          switchStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 32;
        return switchStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder> whileStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public boolean hasWhileStatement() {
        return statementCase_ == 33;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While getWhileStatement() {
        if (whileStatementBuilder_ == null) {
          if (statementCase_ == 33) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
        } else {
          if (statementCase_ == 33) {
            return whileStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public Builder setWhileStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While value) {
        if (whileStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          whileStatementBuilder_.setMessage(value);
        }
        statementCase_ = 33;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public Builder setWhileStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder builderForValue) {
        if (whileStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          whileStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 33;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public Builder mergeWhileStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While value) {
        if (whileStatementBuilder_ == null) {
          if (statementCase_ == 33 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 33) {
            whileStatementBuilder_.mergeFrom(value);
          }
          whileStatementBuilder_.setMessage(value);
        }
        statementCase_ = 33;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public Builder clearWhileStatement() {
        if (whileStatementBuilder_ == null) {
          if (statementCase_ == 33) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 33) {
            statementCase_ = 0;
            statement_ = null;
          }
          whileStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder getWhileStatementBuilder() {
        return getWhileStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder getWhileStatementOrBuilder() {
        if ((statementCase_ == 33) && (whileStatementBuilder_ != null)) {
          return whileStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 33) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.While while_statement = 33;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder> 
          getWhileStatementFieldBuilder() {
        if (whileStatementBuilder_ == null) {
          if (!(statementCase_ == 33)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
          }
          whileStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 33;
        return whileStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder> doWhileStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public boolean hasDoWhileStatement() {
        return statementCase_ == 34;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile getDoWhileStatement() {
        if (doWhileStatementBuilder_ == null) {
          if (statementCase_ == 34) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
        } else {
          if (statementCase_ == 34) {
            return doWhileStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public Builder setDoWhileStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile value) {
        if (doWhileStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          doWhileStatementBuilder_.setMessage(value);
        }
        statementCase_ = 34;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public Builder setDoWhileStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder builderForValue) {
        if (doWhileStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          doWhileStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 34;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public Builder mergeDoWhileStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile value) {
        if (doWhileStatementBuilder_ == null) {
          if (statementCase_ == 34 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 34) {
            doWhileStatementBuilder_.mergeFrom(value);
          }
          doWhileStatementBuilder_.setMessage(value);
        }
        statementCase_ = 34;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public Builder clearDoWhileStatement() {
        if (doWhileStatementBuilder_ == null) {
          if (statementCase_ == 34) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 34) {
            statementCase_ = 0;
            statement_ = null;
          }
          doWhileStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder getDoWhileStatementBuilder() {
        return getDoWhileStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder getDoWhileStatementOrBuilder() {
        if ((statementCase_ == 34) && (doWhileStatementBuilder_ != null)) {
          return doWhileStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 34) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.DoWhile do_while_statement = 34;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder> 
          getDoWhileStatementFieldBuilder() {
        if (doWhileStatementBuilder_ == null) {
          if (!(statementCase_ == 34)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
          }
          doWhileStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 34;
        return doWhileStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder> forStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public boolean hasForStatement() {
        return statementCase_ == 35;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For getForStatement() {
        if (forStatementBuilder_ == null) {
          if (statementCase_ == 35) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
        } else {
          if (statementCase_ == 35) {
            return forStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public Builder setForStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For value) {
        if (forStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          forStatementBuilder_.setMessage(value);
        }
        statementCase_ = 35;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public Builder setForStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder builderForValue) {
        if (forStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          forStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 35;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public Builder mergeForStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For value) {
        if (forStatementBuilder_ == null) {
          if (statementCase_ == 35 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 35) {
            forStatementBuilder_.mergeFrom(value);
          }
          forStatementBuilder_.setMessage(value);
        }
        statementCase_ = 35;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public Builder clearForStatement() {
        if (forStatementBuilder_ == null) {
          if (statementCase_ == 35) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 35) {
            statementCase_ = 0;
            statement_ = null;
          }
          forStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder getForStatementBuilder() {
        return getForStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder getForStatementOrBuilder() {
        if ((statementCase_ == 35) && (forStatementBuilder_ != null)) {
          return forStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 35) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.For for_statement = 35;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder> 
          getForStatementFieldBuilder() {
        if (forStatementBuilder_ == null) {
          if (!(statementCase_ == 35)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
          }
          forStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 35;
        return forStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder> forInStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public boolean hasForInStatement() {
        return statementCase_ == 36;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn getForInStatement() {
        if (forInStatementBuilder_ == null) {
          if (statementCase_ == 36) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
        } else {
          if (statementCase_ == 36) {
            return forInStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public Builder setForInStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn value) {
        if (forInStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          forInStatementBuilder_.setMessage(value);
        }
        statementCase_ = 36;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public Builder setForInStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder builderForValue) {
        if (forInStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          forInStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 36;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public Builder mergeForInStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn value) {
        if (forInStatementBuilder_ == null) {
          if (statementCase_ == 36 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 36) {
            forInStatementBuilder_.mergeFrom(value);
          }
          forInStatementBuilder_.setMessage(value);
        }
        statementCase_ = 36;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public Builder clearForInStatement() {
        if (forInStatementBuilder_ == null) {
          if (statementCase_ == 36) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 36) {
            statementCase_ = 0;
            statement_ = null;
          }
          forInStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder getForInStatementBuilder() {
        return getForInStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder getForInStatementOrBuilder() {
        if ((statementCase_ == 36) && (forInStatementBuilder_ != null)) {
          return forInStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 36) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.ForIn for_in_statement = 36;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder> 
          getForInStatementFieldBuilder() {
        if (forInStatementBuilder_ == null) {
          if (!(statementCase_ == 36)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
          }
          forInStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 36;
        return forInStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder> tryStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public boolean hasTryStatement() {
        return statementCase_ == 37;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try getTryStatement() {
        if (tryStatementBuilder_ == null) {
          if (statementCase_ == 37) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
        } else {
          if (statementCase_ == 37) {
            return tryStatementBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public Builder setTryStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try value) {
        if (tryStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          tryStatementBuilder_.setMessage(value);
        }
        statementCase_ = 37;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public Builder setTryStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder builderForValue) {
        if (tryStatementBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          tryStatementBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 37;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public Builder mergeTryStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try value) {
        if (tryStatementBuilder_ == null) {
          if (statementCase_ == 37 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 37) {
            tryStatementBuilder_.mergeFrom(value);
          }
          tryStatementBuilder_.setMessage(value);
        }
        statementCase_ = 37;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public Builder clearTryStatement() {
        if (tryStatementBuilder_ == null) {
          if (statementCase_ == 37) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 37) {
            statementCase_ = 0;
            statement_ = null;
          }
          tryStatementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder getTryStatementBuilder() {
        return getTryStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder getTryStatementOrBuilder() {
        if ((statementCase_ == 37) && (tryStatementBuilder_ != null)) {
          return tryStatementBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 37) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Try try_statement = 37;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder> 
          getTryStatementFieldBuilder() {
        if (tryStatementBuilder_ == null) {
          if (!(statementCase_ == 37)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
          }
          tryStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 37;
        return tryStatementBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder> emptyBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public boolean hasEmpty() {
        return statementCase_ == 38;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty getEmpty() {
        if (emptyBuilder_ == null) {
          if (statementCase_ == 38) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
        } else {
          if (statementCase_ == 38) {
            return emptyBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public Builder setEmpty(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty value) {
        if (emptyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          statement_ = value;
          onChanged();
        } else {
          emptyBuilder_.setMessage(value);
        }
        statementCase_ = 38;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public Builder setEmpty(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder builderForValue) {
        if (emptyBuilder_ == null) {
          statement_ = builderForValue.build();
          onChanged();
        } else {
          emptyBuilder_.setMessage(builderForValue.build());
        }
        statementCase_ = 38;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public Builder mergeEmpty(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty value) {
        if (emptyBuilder_ == null) {
          if (statementCase_ == 38 &&
              statement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance()) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_)
                .mergeFrom(value).buildPartial();
          } else {
            statement_ = value;
          }
          onChanged();
        } else {
          if (statementCase_ == 38) {
            emptyBuilder_.mergeFrom(value);
          }
          emptyBuilder_.setMessage(value);
        }
        statementCase_ = 38;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public Builder clearEmpty() {
        if (emptyBuilder_ == null) {
          if (statementCase_ == 38) {
            statementCase_ = 0;
            statement_ = null;
            onChanged();
          }
        } else {
          if (statementCase_ == 38) {
            statementCase_ = 0;
            statement_ = null;
          }
          emptyBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder getEmptyBuilder() {
        return getEmptyFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder getEmptyOrBuilder() {
        if ((statementCase_ == 38) && (emptyBuilder_ != null)) {
          return emptyBuilder_.getMessageOrBuilder();
        } else {
          if (statementCase_ == 38) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Empty empty = 38;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder> 
          getEmptyFieldBuilder() {
        if (emptyBuilder_ == null) {
          if (!(statementCase_ == 38)) {
            statement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
          }
          emptyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) statement_,
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        statementCase_ = 38;
        return emptyBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Statement)
    }

    static {
      defaultInstance = new Statement(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Statement)
  }

  public interface ReturnOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Return)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
     */
    boolean hasValue();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getValue();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getValueOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Return}
   */
  public static final class Return extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Return)
      ReturnOrBuilder {
    // Use Return.newBuilder() to construct.
    private Return(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Return(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Return defaultInstance;
    public static Return getDefaultInstance() {
      return defaultInstance;
    }

    public Return getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Return(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = value_.toBuilder();
              }
              value_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(value_);
                value_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Return> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Return>() {
      public Return parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Return(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Return> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int VALUE_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
     */
    public boolean hasValue() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getValue() {
      return value_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getValueOrBuilder() {
      return value_;
    }

    private void initFields() {
      value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (hasValue()) {
        if (!getValue().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, value_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, value_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Return}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Return)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ReturnOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getValueFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (valueBuilder_ == null) {
          value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          valueBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (valueBuilder_ == null) {
          result.value_ = value_;
        } else {
          result.value_ = valueBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return.getDefaultInstance()) return this;
        if (other.hasValue()) {
          mergeValue(other.getValue());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (hasValue()) {
          if (!getValue().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Return) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> valueBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getValue() {
        if (valueBuilder_ == null) {
          return value_;
        } else {
          return valueBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public Builder setValue(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (valueBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          value_ = value;
          onChanged();
        } else {
          valueBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public Builder setValue(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (valueBuilder_ == null) {
          value_ = builderForValue.build();
          onChanged();
        } else {
          valueBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public Builder mergeValue(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (valueBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              value_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            value_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(value_).mergeFrom(value).buildPartial();
          } else {
            value_ = value;
          }
          onChanged();
        } else {
          valueBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public Builder clearValue() {
        if (valueBuilder_ == null) {
          value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          valueBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getValueBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getValueFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getValueOrBuilder() {
        if (valueBuilder_ != null) {
          return valueBuilder_.getMessageOrBuilder();
        } else {
          return value_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression value = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getValueFieldBuilder() {
        if (valueBuilder_ == null) {
          valueBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getValue(),
                  getParentForChildren(),
                  isClean());
          value_ = null;
        }
        return valueBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Return)
    }

    static {
      defaultInstance = new Return(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Return)
  }

  public interface ThrowOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Throw)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
     */
    boolean hasException();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getException();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExceptionOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Throw}
   */
  public static final class Throw extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Throw)
      ThrowOrBuilder {
    // Use Throw.newBuilder() to construct.
    private Throw(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Throw(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Throw defaultInstance;
    public static Throw getDefaultInstance() {
      return defaultInstance;
    }

    public Throw getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Throw(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = exception_.toBuilder();
              }
              exception_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(exception_);
                exception_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Throw> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Throw>() {
      public Throw parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Throw(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Throw> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int EXCEPTION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression exception_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getException() {
      return exception_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExceptionOrBuilder() {
      return exception_;
    }

    private void initFields() {
      exception_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasException()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getException().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, exception_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, exception_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Throw}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Throw)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ThrowOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getExceptionFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (exceptionBuilder_ == null) {
          exception_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          exceptionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (exceptionBuilder_ == null) {
          result.exception_ = exception_;
        } else {
          result.exception_ = exceptionBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw.getDefaultInstance()) return this;
        if (other.hasException()) {
          mergeException(other.getException());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasException()) {
          
          return false;
        }
        if (!getException().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Throw) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression exception_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> exceptionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getException() {
        if (exceptionBuilder_ == null) {
          return exception_;
        } else {
          return exceptionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public Builder setException(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (exceptionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          exception_ = value;
          onChanged();
        } else {
          exceptionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public Builder setException(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (exceptionBuilder_ == null) {
          exception_ = builderForValue.build();
          onChanged();
        } else {
          exceptionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public Builder mergeException(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (exceptionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              exception_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            exception_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(exception_).mergeFrom(value).buildPartial();
          } else {
            exception_ = value;
          }
          onChanged();
        } else {
          exceptionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public Builder clearException() {
        if (exceptionBuilder_ == null) {
          exception_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          exceptionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExceptionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getExceptionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExceptionOrBuilder() {
        if (exceptionBuilder_ != null) {
          return exceptionBuilder_.getMessageOrBuilder();
        } else {
          return exception_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression exception = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExceptionFieldBuilder() {
        if (exceptionBuilder_ == null) {
          exceptionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getException(),
                  getParentForChildren(),
                  isClean());
          exception_ = null;
        }
        return exceptionBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Throw)
    }

    static {
      defaultInstance = new Throw(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Throw)
  }

  public interface BreakOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Break)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 label_id = 1;</code>
     */
    boolean hasLabelId();
    /**
     * <code>optional int32 label_id = 1;</code>
     */
    int getLabelId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Break}
   */
  public static final class Break extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Break)
      BreakOrBuilder {
    // Use Break.newBuilder() to construct.
    private Break(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Break(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Break defaultInstance;
    public static Break getDefaultInstance() {
      return defaultInstance;
    }

    public Break getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Break(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              labelId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Break> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Break>() {
      public Break parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Break(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Break> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int LABEL_ID_FIELD_NUMBER = 1;
    private int labelId_;
    /**
     * <code>optional int32 label_id = 1;</code>
     */
    public boolean hasLabelId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 label_id = 1;</code>
     */
    public int getLabelId() {
      return labelId_;
    }

    private void initFields() {
      labelId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, labelId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, labelId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Break}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Break)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BreakOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        labelId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.labelId_ = labelId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break.getDefaultInstance()) return this;
        if (other.hasLabelId()) {
          setLabelId(other.getLabelId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Break) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int labelId_ ;
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public boolean hasLabelId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public int getLabelId() {
        return labelId_;
      }
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public Builder setLabelId(int value) {
        bitField0_ |= 0x00000001;
        labelId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public Builder clearLabelId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        labelId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Break)
    }

    static {
      defaultInstance = new Break(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Break)
  }

  public interface ContinueOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Continue)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 label_id = 1;</code>
     */
    boolean hasLabelId();
    /**
     * <code>optional int32 label_id = 1;</code>
     */
    int getLabelId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Continue}
   */
  public static final class Continue extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Continue)
      ContinueOrBuilder {
    // Use Continue.newBuilder() to construct.
    private Continue(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Continue(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Continue defaultInstance;
    public static Continue getDefaultInstance() {
      return defaultInstance;
    }

    public Continue getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Continue(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              labelId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Continue> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Continue>() {
      public Continue parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Continue(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Continue> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int LABEL_ID_FIELD_NUMBER = 1;
    private int labelId_;
    /**
     * <code>optional int32 label_id = 1;</code>
     */
    public boolean hasLabelId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 label_id = 1;</code>
     */
    public int getLabelId() {
      return labelId_;
    }

    private void initFields() {
      labelId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, labelId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, labelId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Continue}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Continue)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ContinueOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        labelId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.labelId_ = labelId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue.getDefaultInstance()) return this;
        if (other.hasLabelId()) {
          setLabelId(other.getLabelId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Continue) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int labelId_ ;
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public boolean hasLabelId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public int getLabelId() {
        return labelId_;
      }
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public Builder setLabelId(int value) {
        bitField0_ |= 0x00000001;
        labelId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 label_id = 1;</code>
       */
      public Builder clearLabelId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        labelId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Continue)
    }

    static {
      defaultInstance = new Continue(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Continue)
  }

  public interface DebuggerOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Debugger)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Debugger}
   */
  public static final class Debugger extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Debugger)
      DebuggerOrBuilder {
    // Use Debugger.newBuilder() to construct.
    private Debugger(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Debugger(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Debugger defaultInstance;
    public static Debugger getDefaultInstance() {
      return defaultInstance;
    }

    public Debugger getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Debugger(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Debugger> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Debugger>() {
      public Debugger parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Debugger(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Debugger> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Debugger}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Debugger)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DebuggerOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Debugger) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Debugger)
    }

    static {
      defaultInstance = new Debugger(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Debugger)
  }

  public interface ExpressionStatementOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    boolean hasExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder();

    /**
     * <code>optional int32 exported_tag_id = 2;</code>
     */
    boolean hasExportedTagId();
    /**
     * <code>optional int32 exported_tag_id = 2;</code>
     */
    int getExportedTagId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement}
   */
  public static final class ExpressionStatement extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement)
      ExpressionStatementOrBuilder {
    // Use ExpressionStatement.newBuilder() to construct.
    private ExpressionStatement(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ExpressionStatement(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ExpressionStatement defaultInstance;
    public static ExpressionStatement getDefaultInstance() {
      return defaultInstance;
    }

    public ExpressionStatement getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ExpressionStatement(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = expression_.toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(expression_);
                expression_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              exportedTagId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ExpressionStatement> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ExpressionStatement>() {
      public ExpressionStatement parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ExpressionStatement(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ExpressionStatement> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int EXPRESSION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression expression_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    public boolean hasExpression() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
      return expression_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
      return expression_;
    }

    public static final int EXPORTED_TAG_ID_FIELD_NUMBER = 2;
    private int exportedTagId_;
    /**
     * <code>optional int32 exported_tag_id = 2;</code>
     */
    public boolean hasExportedTagId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 exported_tag_id = 2;</code>
     */
    public int getExportedTagId() {
      return exportedTagId_;
    }

    private void initFields() {
      expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      exportedTagId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasExpression()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getExpression().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, expression_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, exportedTagId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, expression_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, exportedTagId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatementOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getExpressionFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (expressionBuilder_ == null) {
          expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          expressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        exportedTagId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (expressionBuilder_ == null) {
          result.expression_ = expression_;
        } else {
          result.expression_ = expressionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exportedTagId_ = exportedTagId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement.getDefaultInstance()) return this;
        if (other.hasExpression()) {
          mergeExpression(other.getExpression());
        }
        if (other.hasExportedTagId()) {
          setExportedTagId(other.getExportedTagId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasExpression()) {
          
          return false;
        }
        if (!getExpression().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionStatement) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> expressionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public boolean hasExpression() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
        if (expressionBuilder_ == null) {
          return expression_;
        } else {
          return expressionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            expression_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(expression_).mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          expressionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          expressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExpressionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
        if (expressionBuilder_ != null) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          return expression_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getExpression(),
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        return expressionBuilder_;
      }

      private int exportedTagId_ ;
      /**
       * <code>optional int32 exported_tag_id = 2;</code>
       */
      public boolean hasExportedTagId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 exported_tag_id = 2;</code>
       */
      public int getExportedTagId() {
        return exportedTagId_;
      }
      /**
       * <code>optional int32 exported_tag_id = 2;</code>
       */
      public Builder setExportedTagId(int value) {
        bitField0_ |= 0x00000002;
        exportedTagId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 exported_tag_id = 2;</code>
       */
      public Builder clearExportedTagId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        exportedTagId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement)
    }

    static {
      defaultInstance = new ExpressionStatement(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ExpressionStatement)
  }

  public interface VarsOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Vars)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration> 
        getDeclarationList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration getDeclaration(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    int getDeclarationCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder> 
        getDeclarationOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder getDeclarationOrBuilder(
        int index);

    /**
     * <code>optional bool multiline = 2 [default = false];</code>
     */
    boolean hasMultiline();
    /**
     * <code>optional bool multiline = 2 [default = false];</code>
     */
    boolean getMultiline();

    /**
     * <code>optional int32 exported_package_id = 3;</code>
     */
    boolean hasExportedPackageId();
    /**
     * <code>optional int32 exported_package_id = 3;</code>
     */
    int getExportedPackageId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Vars}
   */
  public static final class Vars extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Vars)
      VarsOrBuilder {
    // Use Vars.newBuilder() to construct.
    private Vars(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Vars(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Vars defaultInstance;
    public static Vars getDefaultInstance() {
      return defaultInstance;
    }

    public Vars getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Vars(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                declaration_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration>();
                mutable_bitField0_ |= 0x00000001;
              }
              declaration_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.PARSER, extensionRegistry));
              break;
            }
            case 16: {
              bitField0_ |= 0x00000001;
              multiline_ = input.readBool();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000002;
              exportedPackageId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          declaration_ = java.util.Collections.unmodifiableList(declaration_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Vars> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Vars>() {
      public Vars parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Vars(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Vars> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int DECLARATION_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration> declaration_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration> getDeclarationList() {
      return declaration_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder> 
        getDeclarationOrBuilderList() {
      return declaration_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    public int getDeclarationCount() {
      return declaration_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration getDeclaration(int index) {
      return declaration_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder getDeclarationOrBuilder(
        int index) {
      return declaration_.get(index);
    }

    public static final int MULTILINE_FIELD_NUMBER = 2;
    private boolean multiline_;
    /**
     * <code>optional bool multiline = 2 [default = false];</code>
     */
    public boolean hasMultiline() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional bool multiline = 2 [default = false];</code>
     */
    public boolean getMultiline() {
      return multiline_;
    }

    public static final int EXPORTED_PACKAGE_ID_FIELD_NUMBER = 3;
    private int exportedPackageId_;
    /**
     * <code>optional int32 exported_package_id = 3;</code>
     */
    public boolean hasExportedPackageId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 exported_package_id = 3;</code>
     */
    public int getExportedPackageId() {
      return exportedPackageId_;
    }

    private void initFields() {
      declaration_ = java.util.Collections.emptyList();
      multiline_ = false;
      exportedPackageId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getDeclarationCount(); i++) {
        if (!getDeclaration(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < declaration_.size(); i++) {
        output.writeMessage(1, declaration_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(2, multiline_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(3, exportedPackageId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < declaration_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, declaration_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(2, multiline_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(3, exportedPackageId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Vars}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Vars)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarsOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getDeclarationFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (declarationBuilder_ == null) {
          declaration_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          declarationBuilder_.clear();
        }
        multiline_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        exportedPackageId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (declarationBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            declaration_ = java.util.Collections.unmodifiableList(declaration_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.declaration_ = declaration_;
        } else {
          result.declaration_ = declarationBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.multiline_ = multiline_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.exportedPackageId_ = exportedPackageId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars.getDefaultInstance()) return this;
        if (declarationBuilder_ == null) {
          if (!other.declaration_.isEmpty()) {
            if (declaration_.isEmpty()) {
              declaration_ = other.declaration_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureDeclarationIsMutable();
              declaration_.addAll(other.declaration_);
            }
            onChanged();
          }
        } else {
          if (!other.declaration_.isEmpty()) {
            if (declarationBuilder_.isEmpty()) {
              declarationBuilder_.dispose();
              declarationBuilder_ = null;
              declaration_ = other.declaration_;
              bitField0_ = (bitField0_ & ~0x00000001);
              declarationBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getDeclarationFieldBuilder() : null;
            } else {
              declarationBuilder_.addAllMessages(other.declaration_);
            }
          }
        }
        if (other.hasMultiline()) {
          setMultiline(other.getMultiline());
        }
        if (other.hasExportedPackageId()) {
          setExportedPackageId(other.getExportedPackageId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getDeclarationCount(); i++) {
          if (!getDeclaration(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Vars) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration> declaration_ =
        java.util.Collections.emptyList();
      private void ensureDeclarationIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          declaration_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration>(declaration_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder> declarationBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration> getDeclarationList() {
        if (declarationBuilder_ == null) {
          return java.util.Collections.unmodifiableList(declaration_);
        } else {
          return declarationBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public int getDeclarationCount() {
        if (declarationBuilder_ == null) {
          return declaration_.size();
        } else {
          return declarationBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration getDeclaration(int index) {
        if (declarationBuilder_ == null) {
          return declaration_.get(index);
        } else {
          return declarationBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder setDeclaration(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration value) {
        if (declarationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDeclarationIsMutable();
          declaration_.set(index, value);
          onChanged();
        } else {
          declarationBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder setDeclaration(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder builderForValue) {
        if (declarationBuilder_ == null) {
          ensureDeclarationIsMutable();
          declaration_.set(index, builderForValue.build());
          onChanged();
        } else {
          declarationBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder addDeclaration(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration value) {
        if (declarationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDeclarationIsMutable();
          declaration_.add(value);
          onChanged();
        } else {
          declarationBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder addDeclaration(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration value) {
        if (declarationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureDeclarationIsMutable();
          declaration_.add(index, value);
          onChanged();
        } else {
          declarationBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder addDeclaration(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder builderForValue) {
        if (declarationBuilder_ == null) {
          ensureDeclarationIsMutable();
          declaration_.add(builderForValue.build());
          onChanged();
        } else {
          declarationBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder addDeclaration(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder builderForValue) {
        if (declarationBuilder_ == null) {
          ensureDeclarationIsMutable();
          declaration_.add(index, builderForValue.build());
          onChanged();
        } else {
          declarationBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder addAllDeclaration(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration> values) {
        if (declarationBuilder_ == null) {
          ensureDeclarationIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, declaration_);
          onChanged();
        } else {
          declarationBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder clearDeclaration() {
        if (declarationBuilder_ == null) {
          declaration_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          declarationBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public Builder removeDeclaration(int index) {
        if (declarationBuilder_ == null) {
          ensureDeclarationIsMutable();
          declaration_.remove(index);
          onChanged();
        } else {
          declarationBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder getDeclarationBuilder(
          int index) {
        return getDeclarationFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder getDeclarationOrBuilder(
          int index) {
        if (declarationBuilder_ == null) {
          return declaration_.get(index);  } else {
          return declarationBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder> 
           getDeclarationOrBuilderList() {
        if (declarationBuilder_ != null) {
          return declarationBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(declaration_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder addDeclarationBuilder() {
        return getDeclarationFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder addDeclarationBuilder(
          int index) {
        return getDeclarationFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.VarDeclaration declaration = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder> 
           getDeclarationBuilderList() {
        return getDeclarationFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder> 
          getDeclarationFieldBuilder() {
        if (declarationBuilder_ == null) {
          declarationBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder>(
                  declaration_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          declaration_ = null;
        }
        return declarationBuilder_;
      }

      private boolean multiline_ ;
      /**
       * <code>optional bool multiline = 2 [default = false];</code>
       */
      public boolean hasMultiline() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bool multiline = 2 [default = false];</code>
       */
      public boolean getMultiline() {
        return multiline_;
      }
      /**
       * <code>optional bool multiline = 2 [default = false];</code>
       */
      public Builder setMultiline(boolean value) {
        bitField0_ |= 0x00000002;
        multiline_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool multiline = 2 [default = false];</code>
       */
      public Builder clearMultiline() {
        bitField0_ = (bitField0_ & ~0x00000002);
        multiline_ = false;
        onChanged();
        return this;
      }

      private int exportedPackageId_ ;
      /**
       * <code>optional int32 exported_package_id = 3;</code>
       */
      public boolean hasExportedPackageId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 exported_package_id = 3;</code>
       */
      public int getExportedPackageId() {
        return exportedPackageId_;
      }
      /**
       * <code>optional int32 exported_package_id = 3;</code>
       */
      public Builder setExportedPackageId(int value) {
        bitField0_ |= 0x00000004;
        exportedPackageId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 exported_package_id = 3;</code>
       */
      public Builder clearExportedPackageId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        exportedPackageId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Vars)
    }

    static {
      defaultInstance = new Vars(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Vars)
  }

  public interface VarDeclarationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.VarDeclaration)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 name_id = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 name_id = 1;</code>
     */
    int getNameId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
     */
    boolean hasInitialValue();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getInitialValue();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getInitialValueOrBuilder();

    /**
     * <code>optional int32 fileId = 3;</code>
     */
    boolean hasFileId();
    /**
     * <code>optional int32 fileId = 3;</code>
     */
    int getFileId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    boolean hasLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.VarDeclaration}
   */
  public static final class VarDeclaration extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.VarDeclaration)
      VarDeclarationOrBuilder {
    // Use VarDeclaration.newBuilder() to construct.
    private VarDeclaration(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private VarDeclaration(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final VarDeclaration defaultInstance;
    public static VarDeclaration getDefaultInstance() {
      return defaultInstance;
    }

    public VarDeclaration getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private VarDeclaration(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = initialValue_.toBuilder();
              }
              initialValue_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(initialValue_);
                initialValue_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              fileId_ = input.readInt32();
              break;
            }
            case 34: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = location_.toBuilder();
              }
              location_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(location_);
                location_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<VarDeclaration> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<VarDeclaration>() {
      public VarDeclaration parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new VarDeclaration(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<VarDeclaration> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int NAME_ID_FIELD_NUMBER = 1;
    private int nameId_;
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int INITIAL_VALUE_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression initialValue_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
     */
    public boolean hasInitialValue() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getInitialValue() {
      return initialValue_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getInitialValueOrBuilder() {
      return initialValue_;
    }

    public static final int FILEID_FIELD_NUMBER = 3;
    private int fileId_;
    /**
     * <code>optional int32 fileId = 3;</code>
     */
    public boolean hasFileId() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int32 fileId = 3;</code>
     */
    public int getFileId() {
      return fileId_;
    }

    public static final int LOCATION_FIELD_NUMBER = 4;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    public boolean hasLocation() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
      return location_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
      return location_;
    }

    private void initFields() {
      nameId_ = 0;
      initialValue_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      fileId_ = 0;
      location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasInitialValue()) {
        if (!getInitialValue().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasLocation()) {
        if (!getLocation().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, initialValue_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(3, fileId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, location_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, initialValue_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(3, fileId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(4, location_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.VarDeclaration}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.VarDeclaration)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclarationOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getInitialValueFieldBuilder();
          getLocationFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (initialValueBuilder_ == null) {
          initialValue_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          initialValueBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        fileId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (initialValueBuilder_ == null) {
          result.initialValue_ = initialValue_;
        } else {
          result.initialValue_ = initialValueBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.fileId_ = fileId_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (locationBuilder_ == null) {
          result.location_ = location_;
        } else {
          result.location_ = locationBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration.getDefaultInstance()) return this;
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        if (other.hasInitialValue()) {
          mergeInitialValue(other.getInitialValue());
        }
        if (other.hasFileId()) {
          setFileId(other.getFileId());
        }
        if (other.hasLocation()) {
          mergeLocation(other.getLocation());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasNameId()) {
          
          return false;
        }
        if (hasInitialValue()) {
          if (!getInitialValue().isInitialized()) {
            
            return false;
          }
        }
        if (hasLocation()) {
          if (!getLocation().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.VarDeclaration) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int nameId_ ;
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000001;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression initialValue_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> initialValueBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public boolean hasInitialValue() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getInitialValue() {
        if (initialValueBuilder_ == null) {
          return initialValue_;
        } else {
          return initialValueBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public Builder setInitialValue(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (initialValueBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          initialValue_ = value;
          onChanged();
        } else {
          initialValueBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public Builder setInitialValue(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (initialValueBuilder_ == null) {
          initialValue_ = builderForValue.build();
          onChanged();
        } else {
          initialValueBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public Builder mergeInitialValue(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (initialValueBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              initialValue_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            initialValue_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(initialValue_).mergeFrom(value).buildPartial();
          } else {
            initialValue_ = value;
          }
          onChanged();
        } else {
          initialValueBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public Builder clearInitialValue() {
        if (initialValueBuilder_ == null) {
          initialValue_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          initialValueBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getInitialValueBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getInitialValueFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getInitialValueOrBuilder() {
        if (initialValueBuilder_ != null) {
          return initialValueBuilder_.getMessageOrBuilder();
        } else {
          return initialValue_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression initial_value = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getInitialValueFieldBuilder() {
        if (initialValueBuilder_ == null) {
          initialValueBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getInitialValue(),
                  getParentForChildren(),
                  isClean());
          initialValue_ = null;
        }
        return initialValueBuilder_;
      }

      private int fileId_ ;
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public boolean hasFileId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public int getFileId() {
        return fileId_;
      }
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public Builder setFileId(int value) {
        bitField0_ |= 0x00000004;
        fileId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public Builder clearFileId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        fileId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> locationBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public boolean hasLocation() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
        if (locationBuilder_ == null) {
          return location_;
        } else {
          return locationBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder setLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          location_ = value;
          onChanged();
        } else {
          locationBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder setLocation(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder builderForValue) {
        if (locationBuilder_ == null) {
          location_ = builderForValue.build();
          onChanged();
        } else {
          locationBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder mergeLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              location_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance()) {
            location_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.newBuilder(location_).mergeFrom(value).buildPartial();
          } else {
            location_ = value;
          }
          onChanged();
        } else {
          locationBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder clearLocation() {
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
          onChanged();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder getLocationBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getLocationFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
        if (locationBuilder_ != null) {
          return locationBuilder_.getMessageOrBuilder();
        } else {
          return location_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> 
          getLocationFieldBuilder() {
        if (locationBuilder_ == null) {
          locationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder>(
                  getLocation(),
                  getParentForChildren(),
                  isClean());
          location_ = null;
        }
        return locationBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.VarDeclaration)
    }

    static {
      defaultInstance = new VarDeclaration(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.VarDeclaration)
  }

  public interface BlockOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Block)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> 
        getStatementList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    int getStatementCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
        getStatementOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Block}
   */
  public static final class Block extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Block)
      BlockOrBuilder {
    // Use Block.newBuilder() to construct.
    private Block(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Block(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Block defaultInstance;
    public static Block getDefaultInstance() {
      return defaultInstance;
    }

    public Block getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Block(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                statement_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement>();
                mutable_bitField0_ |= 0x00000001;
              }
              statement_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          statement_ = java.util.Collections.unmodifiableList(statement_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Block> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Block>() {
      public Block parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Block(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Block> getParserForType() {
      return PARSER;
    }

    public static final int STATEMENT_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> statement_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> getStatementList() {
      return statement_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
        getStatementOrBuilderList() {
      return statement_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public int getStatementCount() {
      return statement_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index) {
      return statement_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
        int index) {
      return statement_.get(index);
    }

    private void initFields() {
      statement_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getStatementCount(); i++) {
        if (!getStatement(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < statement_.size(); i++) {
        output.writeMessage(1, statement_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < statement_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, statement_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Block}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Block)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.BlockOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getStatementFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (statementBuilder_ == null) {
          statement_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          statementBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block(this);
        int from_bitField0_ = bitField0_;
        if (statementBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            statement_ = java.util.Collections.unmodifiableList(statement_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.statement_ = statement_;
        } else {
          result.statement_ = statementBuilder_.build();
        }
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block.getDefaultInstance()) return this;
        if (statementBuilder_ == null) {
          if (!other.statement_.isEmpty()) {
            if (statement_.isEmpty()) {
              statement_ = other.statement_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureStatementIsMutable();
              statement_.addAll(other.statement_);
            }
            onChanged();
          }
        } else {
          if (!other.statement_.isEmpty()) {
            if (statementBuilder_.isEmpty()) {
              statementBuilder_.dispose();
              statementBuilder_ = null;
              statement_ = other.statement_;
              bitField0_ = (bitField0_ & ~0x00000001);
              statementBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getStatementFieldBuilder() : null;
            } else {
              statementBuilder_.addAllMessages(other.statement_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getStatementCount(); i++) {
          if (!getStatement(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Block) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> statement_ =
        java.util.Collections.emptyList();
      private void ensureStatementIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          statement_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement>(statement_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> statementBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> getStatementList() {
        if (statementBuilder_ == null) {
          return java.util.Collections.unmodifiableList(statement_);
        } else {
          return statementBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public int getStatementCount() {
        if (statementBuilder_ == null) {
          return statement_.size();
        } else {
          return statementBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index) {
        if (statementBuilder_ == null) {
          return statement_.get(index);
        } else {
          return statementBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder setStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.set(index, value);
          onChanged();
        } else {
          statementBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder setStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.set(index, builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.add(value);
          onChanged();
        } else {
          statementBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.add(index, value);
          onChanged();
        } else {
          statementBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.add(builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.add(index, builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addAllStatement(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> values) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, statement_);
          onChanged();
        } else {
          statementBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder clearStatement() {
        if (statementBuilder_ == null) {
          statement_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          statementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder removeStatement(int index) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.remove(index);
          onChanged();
        } else {
          statementBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getStatementBuilder(
          int index) {
        return getStatementFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
          int index) {
        if (statementBuilder_ == null) {
          return statement_.get(index);  } else {
          return statementBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
           getStatementOrBuilderList() {
        if (statementBuilder_ != null) {
          return statementBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(statement_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder addStatementBuilder() {
        return getStatementFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder addStatementBuilder(
          int index) {
        return getStatementFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder> 
           getStatementBuilderList() {
        return getStatementFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getStatementFieldBuilder() {
        if (statementBuilder_ == null) {
          statementBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  statement_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        return statementBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Block)
    }

    static {
      defaultInstance = new Block(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Block)
  }

  public interface GlobalBlockOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.GlobalBlock)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> 
        getStatementList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    int getStatementCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
        getStatementOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.GlobalBlock}
   */
  public static final class GlobalBlock extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.GlobalBlock)
      GlobalBlockOrBuilder {
    // Use GlobalBlock.newBuilder() to construct.
    private GlobalBlock(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private GlobalBlock(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final GlobalBlock defaultInstance;
    public static GlobalBlock getDefaultInstance() {
      return defaultInstance;
    }

    public GlobalBlock getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private GlobalBlock(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                statement_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement>();
                mutable_bitField0_ |= 0x00000001;
              }
              statement_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          statement_ = java.util.Collections.unmodifiableList(statement_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<GlobalBlock> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<GlobalBlock>() {
      public GlobalBlock parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new GlobalBlock(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<GlobalBlock> getParserForType() {
      return PARSER;
    }

    public static final int STATEMENT_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> statement_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> getStatementList() {
      return statement_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
        getStatementOrBuilderList() {
      return statement_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public int getStatementCount() {
      return statement_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index) {
      return statement_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
        int index) {
      return statement_.get(index);
    }

    private void initFields() {
      statement_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getStatementCount(); i++) {
        if (!getStatement(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < statement_.size(); i++) {
        output.writeMessage(1, statement_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < statement_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, statement_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.GlobalBlock}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.GlobalBlock)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getStatementFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (statementBuilder_ == null) {
          statement_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          statementBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock(this);
        int from_bitField0_ = bitField0_;
        if (statementBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            statement_ = java.util.Collections.unmodifiableList(statement_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.statement_ = statement_;
        } else {
          result.statement_ = statementBuilder_.build();
        }
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) return this;
        if (statementBuilder_ == null) {
          if (!other.statement_.isEmpty()) {
            if (statement_.isEmpty()) {
              statement_ = other.statement_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureStatementIsMutable();
              statement_.addAll(other.statement_);
            }
            onChanged();
          }
        } else {
          if (!other.statement_.isEmpty()) {
            if (statementBuilder_.isEmpty()) {
              statementBuilder_.dispose();
              statementBuilder_ = null;
              statement_ = other.statement_;
              bitField0_ = (bitField0_ & ~0x00000001);
              statementBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getStatementFieldBuilder() : null;
            } else {
              statementBuilder_.addAllMessages(other.statement_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getStatementCount(); i++) {
          if (!getStatement(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> statement_ =
        java.util.Collections.emptyList();
      private void ensureStatementIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          statement_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement>(statement_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> statementBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> getStatementList() {
        if (statementBuilder_ == null) {
          return java.util.Collections.unmodifiableList(statement_);
        } else {
          return statementBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public int getStatementCount() {
        if (statementBuilder_ == null) {
          return statement_.size();
        } else {
          return statementBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index) {
        if (statementBuilder_ == null) {
          return statement_.get(index);
        } else {
          return statementBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder setStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.set(index, value);
          onChanged();
        } else {
          statementBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder setStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.set(index, builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.add(value);
          onChanged();
        } else {
          statementBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.add(index, value);
          onChanged();
        } else {
          statementBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.add(builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.add(index, builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder addAllStatement(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> values) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, statement_);
          onChanged();
        } else {
          statementBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder clearStatement() {
        if (statementBuilder_ == null) {
          statement_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          statementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public Builder removeStatement(int index) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.remove(index);
          onChanged();
        } else {
          statementBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getStatementBuilder(
          int index) {
        return getStatementFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
          int index) {
        if (statementBuilder_ == null) {
          return statement_.get(index);  } else {
          return statementBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
           getStatementOrBuilderList() {
        if (statementBuilder_ != null) {
          return statementBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(statement_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder addStatementBuilder() {
        return getStatementFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder addStatementBuilder(
          int index) {
        return getStatementFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder> 
           getStatementBuilderList() {
        return getStatementFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getStatementFieldBuilder() {
        if (statementBuilder_ == null) {
          statementBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  statement_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        return statementBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.GlobalBlock)
    }

    static {
      defaultInstance = new GlobalBlock(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.GlobalBlock)
  }

  public interface LabelOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Label)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 nameId = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 nameId = 1;</code>
     */
    int getNameId();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
     */
    boolean hasInnerStatement();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getInnerStatement();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getInnerStatementOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Label}
   */
  public static final class Label extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Label)
      LabelOrBuilder {
    // Use Label.newBuilder() to construct.
    private Label(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Label(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Label defaultInstance;
    public static Label getDefaultInstance() {
      return defaultInstance;
    }

    public Label getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Label(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = innerStatement_.toBuilder();
              }
              innerStatement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(innerStatement_);
                innerStatement_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Label> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Label>() {
      public Label parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Label(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Label> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int NAMEID_FIELD_NUMBER = 1;
    private int nameId_;
    /**
     * <code>required int32 nameId = 1;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 nameId = 1;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int INNER_STATEMENT_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement innerStatement_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
     */
    public boolean hasInnerStatement() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getInnerStatement() {
      return innerStatement_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getInnerStatementOrBuilder() {
      return innerStatement_;
    }

    private void initFields() {
      nameId_ = 0;
      innerStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasInnerStatement()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getInnerStatement().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, innerStatement_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, innerStatement_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Label}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Label)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LabelOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getInnerStatementFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (innerStatementBuilder_ == null) {
          innerStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          innerStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (innerStatementBuilder_ == null) {
          result.innerStatement_ = innerStatement_;
        } else {
          result.innerStatement_ = innerStatementBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label.getDefaultInstance()) return this;
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        if (other.hasInnerStatement()) {
          mergeInnerStatement(other.getInnerStatement());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasNameId()) {
          
          return false;
        }
        if (!hasInnerStatement()) {
          
          return false;
        }
        if (!getInnerStatement().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Label) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int nameId_ ;
      /**
       * <code>required int32 nameId = 1;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 nameId = 1;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 nameId = 1;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000001;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 nameId = 1;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement innerStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> innerStatementBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public boolean hasInnerStatement() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getInnerStatement() {
        if (innerStatementBuilder_ == null) {
          return innerStatement_;
        } else {
          return innerStatementBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public Builder setInnerStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (innerStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          innerStatement_ = value;
          onChanged();
        } else {
          innerStatementBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public Builder setInnerStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (innerStatementBuilder_ == null) {
          innerStatement_ = builderForValue.build();
          onChanged();
        } else {
          innerStatementBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public Builder mergeInnerStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (innerStatementBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              innerStatement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            innerStatement_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(innerStatement_).mergeFrom(value).buildPartial();
          } else {
            innerStatement_ = value;
          }
          onChanged();
        } else {
          innerStatementBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public Builder clearInnerStatement() {
        if (innerStatementBuilder_ == null) {
          innerStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          innerStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getInnerStatementBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getInnerStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getInnerStatementOrBuilder() {
        if (innerStatementBuilder_ != null) {
          return innerStatementBuilder_.getMessageOrBuilder();
        } else {
          return innerStatement_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement inner_statement = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getInnerStatementFieldBuilder() {
        if (innerStatementBuilder_ == null) {
          innerStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getInnerStatement(),
                  getParentForChildren(),
                  isClean());
          innerStatement_ = null;
        }
        return innerStatementBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Label)
    }

    static {
      defaultInstance = new Label(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Label)
  }

  public interface IfOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.If)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    boolean hasCondition();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
     */
    boolean hasThenStatement();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getThenStatement();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getThenStatementOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
     */
    boolean hasElseStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getElseStatement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getElseStatementOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.If}
   */
  public static final class If extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.If)
      IfOrBuilder {
    // Use If.newBuilder() to construct.
    private If(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private If(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final If defaultInstance;
    public static If getDefaultInstance() {
      return defaultInstance;
    }

    public If getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private If(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = condition_.toBuilder();
              }
              condition_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(condition_);
                condition_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = thenStatement_.toBuilder();
              }
              thenStatement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(thenStatement_);
                thenStatement_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = elseStatement_.toBuilder();
              }
              elseStatement_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(elseStatement_);
                elseStatement_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_If_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_If_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<If> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<If>() {
      public If parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new If(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<If> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int CONDITION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public boolean hasCondition() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
      return condition_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
      return condition_;
    }

    public static final int THEN_STATEMENT_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement thenStatement_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
     */
    public boolean hasThenStatement() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getThenStatement() {
      return thenStatement_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getThenStatementOrBuilder() {
      return thenStatement_;
    }

    public static final int ELSE_STATEMENT_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement elseStatement_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
     */
    public boolean hasElseStatement() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getElseStatement() {
      return elseStatement_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getElseStatementOrBuilder() {
      return elseStatement_;
    }

    private void initFields() {
      condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      thenStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      elseStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasCondition()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasThenStatement()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getCondition().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getThenStatement().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasElseStatement()) {
        if (!getElseStatement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, condition_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, thenStatement_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, elseStatement_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, condition_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, thenStatement_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, elseStatement_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.If}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.If)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.IfOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_If_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_If_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getConditionFieldBuilder();
          getThenStatementFieldBuilder();
          getElseStatementFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (thenStatementBuilder_ == null) {
          thenStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          thenStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (elseStatementBuilder_ == null) {
          elseStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          elseStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_If_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (conditionBuilder_ == null) {
          result.condition_ = condition_;
        } else {
          result.condition_ = conditionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (thenStatementBuilder_ == null) {
          result.thenStatement_ = thenStatement_;
        } else {
          result.thenStatement_ = thenStatementBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (elseStatementBuilder_ == null) {
          result.elseStatement_ = elseStatement_;
        } else {
          result.elseStatement_ = elseStatementBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If.getDefaultInstance()) return this;
        if (other.hasCondition()) {
          mergeCondition(other.getCondition());
        }
        if (other.hasThenStatement()) {
          mergeThenStatement(other.getThenStatement());
        }
        if (other.hasElseStatement()) {
          mergeElseStatement(other.getElseStatement());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasCondition()) {
          
          return false;
        }
        if (!hasThenStatement()) {
          
          return false;
        }
        if (!getCondition().isInitialized()) {
          
          return false;
        }
        if (!getThenStatement().isInitialized()) {
          
          return false;
        }
        if (hasElseStatement()) {
          if (!getElseStatement().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.If) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> conditionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public boolean hasCondition() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
        if (conditionBuilder_ == null) {
          return condition_;
        } else {
          return conditionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder setCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          condition_ = value;
          onChanged();
        } else {
          conditionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder setCondition(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (conditionBuilder_ == null) {
          condition_ = builderForValue.build();
          onChanged();
        } else {
          conditionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder mergeCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              condition_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            condition_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(condition_).mergeFrom(value).buildPartial();
          } else {
            condition_ = value;
          }
          onChanged();
        } else {
          conditionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder clearCondition() {
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getConditionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getConditionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
        if (conditionBuilder_ != null) {
          return conditionBuilder_.getMessageOrBuilder();
        } else {
          return condition_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getConditionFieldBuilder() {
        if (conditionBuilder_ == null) {
          conditionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getCondition(),
                  getParentForChildren(),
                  isClean());
          condition_ = null;
        }
        return conditionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement thenStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> thenStatementBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public boolean hasThenStatement() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getThenStatement() {
        if (thenStatementBuilder_ == null) {
          return thenStatement_;
        } else {
          return thenStatementBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public Builder setThenStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (thenStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          thenStatement_ = value;
          onChanged();
        } else {
          thenStatementBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public Builder setThenStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (thenStatementBuilder_ == null) {
          thenStatement_ = builderForValue.build();
          onChanged();
        } else {
          thenStatementBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public Builder mergeThenStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (thenStatementBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              thenStatement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            thenStatement_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(thenStatement_).mergeFrom(value).buildPartial();
          } else {
            thenStatement_ = value;
          }
          onChanged();
        } else {
          thenStatementBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public Builder clearThenStatement() {
        if (thenStatementBuilder_ == null) {
          thenStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          thenStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getThenStatementBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getThenStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getThenStatementOrBuilder() {
        if (thenStatementBuilder_ != null) {
          return thenStatementBuilder_.getMessageOrBuilder();
        } else {
          return thenStatement_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement then_statement = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getThenStatementFieldBuilder() {
        if (thenStatementBuilder_ == null) {
          thenStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getThenStatement(),
                  getParentForChildren(),
                  isClean());
          thenStatement_ = null;
        }
        return thenStatementBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement elseStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> elseStatementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public boolean hasElseStatement() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getElseStatement() {
        if (elseStatementBuilder_ == null) {
          return elseStatement_;
        } else {
          return elseStatementBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public Builder setElseStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (elseStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          elseStatement_ = value;
          onChanged();
        } else {
          elseStatementBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public Builder setElseStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (elseStatementBuilder_ == null) {
          elseStatement_ = builderForValue.build();
          onChanged();
        } else {
          elseStatementBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public Builder mergeElseStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (elseStatementBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              elseStatement_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            elseStatement_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(elseStatement_).mergeFrom(value).buildPartial();
          } else {
            elseStatement_ = value;
          }
          onChanged();
        } else {
          elseStatementBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public Builder clearElseStatement() {
        if (elseStatementBuilder_ == null) {
          elseStatement_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          elseStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getElseStatementBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getElseStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getElseStatementOrBuilder() {
        if (elseStatementBuilder_ != null) {
          return elseStatementBuilder_.getMessageOrBuilder();
        } else {
          return elseStatement_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement else_statement = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getElseStatementFieldBuilder() {
        if (elseStatementBuilder_ == null) {
          elseStatementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getElseStatement(),
                  getParentForChildren(),
                  isClean());
          elseStatement_ = null;
        }
        return elseStatementBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.If)
    }

    static {
      defaultInstance = new If(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.If)
  }

  public interface SwitchOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Switch)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    boolean hasExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder();

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry> 
        getEntryList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry getEntry(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    int getEntryCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder> 
        getEntryOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder getEntryOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Switch}
   */
  public static final class Switch extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Switch)
      SwitchOrBuilder {
    // Use Switch.newBuilder() to construct.
    private Switch(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Switch(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Switch defaultInstance;
    public static Switch getDefaultInstance() {
      return defaultInstance;
    }

    public Switch getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Switch(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = expression_.toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(expression_);
                expression_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                entry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry>();
                mutable_bitField0_ |= 0x00000002;
              }
              entry_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          entry_ = java.util.Collections.unmodifiableList(entry_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Switch> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Switch>() {
      public Switch parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Switch(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Switch> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int EXPRESSION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression expression_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    public boolean hasExpression() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
      return expression_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
      return expression_;
    }

    public static final int ENTRY_FIELD_NUMBER = 2;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry> entry_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry> getEntryList() {
      return entry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder> 
        getEntryOrBuilderList() {
      return entry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    public int getEntryCount() {
      return entry_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry getEntry(int index) {
      return entry_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder getEntryOrBuilder(
        int index) {
      return entry_.get(index);
    }

    private void initFields() {
      expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      entry_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasExpression()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getExpression().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getEntryCount(); i++) {
        if (!getEntry(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, expression_);
      }
      for (int i = 0; i < entry_.size(); i++) {
        output.writeMessage(2, entry_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, expression_);
      }
      for (int i = 0; i < entry_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, entry_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Switch}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Switch)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getExpressionFieldBuilder();
          getEntryFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (expressionBuilder_ == null) {
          expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          expressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (entryBuilder_ == null) {
          entry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          entryBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (expressionBuilder_ == null) {
          result.expression_ = expression_;
        } else {
          result.expression_ = expressionBuilder_.build();
        }
        if (entryBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            entry_ = java.util.Collections.unmodifiableList(entry_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.entry_ = entry_;
        } else {
          result.entry_ = entryBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch.getDefaultInstance()) return this;
        if (other.hasExpression()) {
          mergeExpression(other.getExpression());
        }
        if (entryBuilder_ == null) {
          if (!other.entry_.isEmpty()) {
            if (entry_.isEmpty()) {
              entry_ = other.entry_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureEntryIsMutable();
              entry_.addAll(other.entry_);
            }
            onChanged();
          }
        } else {
          if (!other.entry_.isEmpty()) {
            if (entryBuilder_.isEmpty()) {
              entryBuilder_.dispose();
              entryBuilder_ = null;
              entry_ = other.entry_;
              bitField0_ = (bitField0_ & ~0x00000002);
              entryBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getEntryFieldBuilder() : null;
            } else {
              entryBuilder_.addAllMessages(other.entry_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasExpression()) {
          
          return false;
        }
        if (!getExpression().isInitialized()) {
          
          return false;
        }
        for (int i = 0; i < getEntryCount(); i++) {
          if (!getEntry(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Switch) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> expressionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public boolean hasExpression() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
        if (expressionBuilder_ == null) {
          return expression_;
        } else {
          return expressionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            expression_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(expression_).mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          expressionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          expressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExpressionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
        if (expressionBuilder_ != null) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          return expression_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getExpression(),
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        return expressionBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry> entry_ =
        java.util.Collections.emptyList();
      private void ensureEntryIsMutable() {
        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
          entry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry>(entry_);
          bitField0_ |= 0x00000002;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder> entryBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry> getEntryList() {
        if (entryBuilder_ == null) {
          return java.util.Collections.unmodifiableList(entry_);
        } else {
          return entryBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public int getEntryCount() {
        if (entryBuilder_ == null) {
          return entry_.size();
        } else {
          return entryBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry getEntry(int index) {
        if (entryBuilder_ == null) {
          return entry_.get(index);
        } else {
          return entryBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder setEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.set(index, value);
          onChanged();
        } else {
          entryBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder setEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.set(index, builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder addEntry(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.add(value);
          onChanged();
        } else {
          entryBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder addEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.add(index, value);
          onChanged();
        } else {
          entryBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder addEntry(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.add(builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder addEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.add(index, builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder addAllEntry(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry> values) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, entry_);
          onChanged();
        } else {
          entryBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder clearEntry() {
        if (entryBuilder_ == null) {
          entry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          entryBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public Builder removeEntry(int index) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.remove(index);
          onChanged();
        } else {
          entryBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder getEntryBuilder(
          int index) {
        return getEntryFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder getEntryOrBuilder(
          int index) {
        if (entryBuilder_ == null) {
          return entry_.get(index);  } else {
          return entryBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder> 
           getEntryOrBuilderList() {
        if (entryBuilder_ != null) {
          return entryBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(entry_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder addEntryBuilder() {
        return getEntryFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder addEntryBuilder(
          int index) {
        return getEntryFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.SwitchEntry entry = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder> 
           getEntryBuilderList() {
        return getEntryFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder> 
          getEntryFieldBuilder() {
        if (entryBuilder_ == null) {
          entryBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder>(
                  entry_,
                  ((bitField0_ & 0x00000002) == 0x00000002),
                  getParentForChildren(),
                  isClean());
          entry_ = null;
        }
        return entryBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Switch)
    }

    static {
      defaultInstance = new Switch(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Switch)
  }

  public interface SwitchEntryOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.SwitchEntry)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
     */
    boolean hasLabel();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getLabel();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getLabelOrBuilder();

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> 
        getStatementList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    int getStatementCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
        getStatementOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
        int index);

    /**
     * <code>optional int32 fileId = 3;</code>
     */
    boolean hasFileId();
    /**
     * <code>optional int32 fileId = 3;</code>
     */
    int getFileId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    boolean hasLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.SwitchEntry}
   */
  public static final class SwitchEntry extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.SwitchEntry)
      SwitchEntryOrBuilder {
    // Use SwitchEntry.newBuilder() to construct.
    private SwitchEntry(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private SwitchEntry(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final SwitchEntry defaultInstance;
    public static SwitchEntry getDefaultInstance() {
      return defaultInstance;
    }

    public SwitchEntry getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private SwitchEntry(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = label_.toBuilder();
              }
              label_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(label_);
                label_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                statement_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement>();
                mutable_bitField0_ |= 0x00000002;
              }
              statement_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry));
              break;
            }
            case 24: {
              bitField0_ |= 0x00000002;
              fileId_ = input.readInt32();
              break;
            }
            case 34: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = location_.toBuilder();
              }
              location_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(location_);
                location_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          statement_ = java.util.Collections.unmodifiableList(statement_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<SwitchEntry> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<SwitchEntry>() {
      public SwitchEntry parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new SwitchEntry(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<SwitchEntry> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int LABEL_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression label_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
     */
    public boolean hasLabel() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getLabel() {
      return label_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getLabelOrBuilder() {
      return label_;
    }

    public static final int STATEMENT_FIELD_NUMBER = 2;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> statement_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> getStatementList() {
      return statement_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
        getStatementOrBuilderList() {
      return statement_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    public int getStatementCount() {
      return statement_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index) {
      return statement_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
        int index) {
      return statement_.get(index);
    }

    public static final int FILEID_FIELD_NUMBER = 3;
    private int fileId_;
    /**
     * <code>optional int32 fileId = 3;</code>
     */
    public boolean hasFileId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 fileId = 3;</code>
     */
    public int getFileId() {
      return fileId_;
    }

    public static final int LOCATION_FIELD_NUMBER = 4;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    public boolean hasLocation() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
      return location_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
      return location_;
    }

    private void initFields() {
      label_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      statement_ = java.util.Collections.emptyList();
      fileId_ = 0;
      location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (hasLabel()) {
        if (!getLabel().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getStatementCount(); i++) {
        if (!getStatement(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasLocation()) {
        if (!getLocation().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, label_);
      }
      for (int i = 0; i < statement_.size(); i++) {
        output.writeMessage(2, statement_.get(i));
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(3, fileId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(4, location_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, label_);
      }
      for (int i = 0; i < statement_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, statement_.get(i));
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(3, fileId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(4, location_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.SwitchEntry}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.SwitchEntry)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntryOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getLabelFieldBuilder();
          getStatementFieldBuilder();
          getLocationFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (labelBuilder_ == null) {
          label_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          labelBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (statementBuilder_ == null) {
          statement_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          statementBuilder_.clear();
        }
        fileId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (labelBuilder_ == null) {
          result.label_ = label_;
        } else {
          result.label_ = labelBuilder_.build();
        }
        if (statementBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            statement_ = java.util.Collections.unmodifiableList(statement_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.statement_ = statement_;
        } else {
          result.statement_ = statementBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.fileId_ = fileId_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        if (locationBuilder_ == null) {
          result.location_ = location_;
        } else {
          result.location_ = locationBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry.getDefaultInstance()) return this;
        if (other.hasLabel()) {
          mergeLabel(other.getLabel());
        }
        if (statementBuilder_ == null) {
          if (!other.statement_.isEmpty()) {
            if (statement_.isEmpty()) {
              statement_ = other.statement_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureStatementIsMutable();
              statement_.addAll(other.statement_);
            }
            onChanged();
          }
        } else {
          if (!other.statement_.isEmpty()) {
            if (statementBuilder_.isEmpty()) {
              statementBuilder_.dispose();
              statementBuilder_ = null;
              statement_ = other.statement_;
              bitField0_ = (bitField0_ & ~0x00000002);
              statementBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getStatementFieldBuilder() : null;
            } else {
              statementBuilder_.addAllMessages(other.statement_);
            }
          }
        }
        if (other.hasFileId()) {
          setFileId(other.getFileId());
        }
        if (other.hasLocation()) {
          mergeLocation(other.getLocation());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (hasLabel()) {
          if (!getLabel().isInitialized()) {
            
            return false;
          }
        }
        for (int i = 0; i < getStatementCount(); i++) {
          if (!getStatement(i).isInitialized()) {
            
            return false;
          }
        }
        if (hasLocation()) {
          if (!getLocation().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SwitchEntry) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression label_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> labelBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public boolean hasLabel() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getLabel() {
        if (labelBuilder_ == null) {
          return label_;
        } else {
          return labelBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public Builder setLabel(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (labelBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          label_ = value;
          onChanged();
        } else {
          labelBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public Builder setLabel(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (labelBuilder_ == null) {
          label_ = builderForValue.build();
          onChanged();
        } else {
          labelBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public Builder mergeLabel(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (labelBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              label_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            label_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(label_).mergeFrom(value).buildPartial();
          } else {
            label_ = value;
          }
          onChanged();
        } else {
          labelBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public Builder clearLabel() {
        if (labelBuilder_ == null) {
          label_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          labelBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getLabelBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getLabelFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getLabelOrBuilder() {
        if (labelBuilder_ != null) {
          return labelBuilder_.getMessageOrBuilder();
        } else {
          return label_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression label = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getLabelFieldBuilder() {
        if (labelBuilder_ == null) {
          labelBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getLabel(),
                  getParentForChildren(),
                  isClean());
          label_ = null;
        }
        return labelBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> statement_ =
        java.util.Collections.emptyList();
      private void ensureStatementIsMutable() {
        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
          statement_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement>(statement_);
          bitField0_ |= 0x00000002;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> statementBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> getStatementList() {
        if (statementBuilder_ == null) {
          return java.util.Collections.unmodifiableList(statement_);
        } else {
          return statementBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public int getStatementCount() {
        if (statementBuilder_ == null) {
          return statement_.size();
        } else {
          return statementBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getStatement(int index) {
        if (statementBuilder_ == null) {
          return statement_.get(index);
        } else {
          return statementBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder setStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.set(index, value);
          onChanged();
        } else {
          statementBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder setStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.set(index, builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder addStatement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.add(value);
          onChanged();
        } else {
          statementBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder addStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (statementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureStatementIsMutable();
          statement_.add(index, value);
          onChanged();
        } else {
          statementBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder addStatement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.add(builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder addStatement(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.add(index, builderForValue.build());
          onChanged();
        } else {
          statementBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder addAllStatement(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement> values) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, statement_);
          onChanged();
        } else {
          statementBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder clearStatement() {
        if (statementBuilder_ == null) {
          statement_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          statementBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public Builder removeStatement(int index) {
        if (statementBuilder_ == null) {
          ensureStatementIsMutable();
          statement_.remove(index);
          onChanged();
        } else {
          statementBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getStatementBuilder(
          int index) {
        return getStatementFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getStatementOrBuilder(
          int index) {
        if (statementBuilder_ == null) {
          return statement_.get(index);  } else {
          return statementBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
           getStatementOrBuilderList() {
        if (statementBuilder_ != null) {
          return statementBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(statement_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder addStatementBuilder() {
        return getStatementFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder addStatementBuilder(
          int index) {
        return getStatementFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Statement statement = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder> 
           getStatementBuilderList() {
        return getStatementFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getStatementFieldBuilder() {
        if (statementBuilder_ == null) {
          statementBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  statement_,
                  ((bitField0_ & 0x00000002) == 0x00000002),
                  getParentForChildren(),
                  isClean());
          statement_ = null;
        }
        return statementBuilder_;
      }

      private int fileId_ ;
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public boolean hasFileId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public int getFileId() {
        return fileId_;
      }
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public Builder setFileId(int value) {
        bitField0_ |= 0x00000004;
        fileId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 fileId = 3;</code>
       */
      public Builder clearFileId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        fileId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> locationBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public boolean hasLocation() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location getLocation() {
        if (locationBuilder_ == null) {
          return location_;
        } else {
          return locationBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder setLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          location_ = value;
          onChanged();
        } else {
          locationBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder setLocation(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder builderForValue) {
        if (locationBuilder_ == null) {
          location_ = builderForValue.build();
          onChanged();
        } else {
          locationBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder mergeLocation(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location value) {
        if (locationBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              location_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance()) {
            location_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.newBuilder(location_).mergeFrom(value).buildPartial();
          } else {
            location_ = value;
          }
          onChanged();
        } else {
          locationBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public Builder clearLocation() {
        if (locationBuilder_ == null) {
          location_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.getDefaultInstance();
          onChanged();
        } else {
          locationBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder getLocationBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getLocationFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder getLocationOrBuilder() {
        if (locationBuilder_ != null) {
          return locationBuilder_.getMessageOrBuilder();
        } else {
          return location_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Location location = 4;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder> 
          getLocationFieldBuilder() {
        if (locationBuilder_ == null) {
          locationBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Location.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.LocationOrBuilder>(
                  getLocation(),
                  getParentForChildren(),
                  isClean());
          location_ = null;
        }
        return locationBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.SwitchEntry)
    }

    static {
      defaultInstance = new SwitchEntry(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.SwitchEntry)
  }

  public interface WhileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.While)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    boolean hasCondition();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    boolean hasBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.While}
   */
  public static final class While extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.While)
      WhileOrBuilder {
    // Use While.newBuilder() to construct.
    private While(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private While(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final While defaultInstance;
    public static While getDefaultInstance() {
      return defaultInstance;
    }

    public While getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private While(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = condition_.toBuilder();
              }
              condition_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(condition_);
                condition_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = body_.toBuilder();
              }
              body_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(body_);
                body_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_While_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<While> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<While>() {
      public While parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new While(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<While> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int CONDITION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public boolean hasCondition() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
      return condition_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
      return condition_;
    }

    public static final int BODY_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public boolean hasBody() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
      return body_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
      return body_;
    }

    private void initFields() {
      condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasCondition()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasBody()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getCondition().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getBody().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, condition_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, body_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, condition_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, body_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.While}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.While)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.WhileOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_While_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getConditionFieldBuilder();
          getBodyFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (conditionBuilder_ == null) {
          result.condition_ = condition_;
        } else {
          result.condition_ = conditionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (bodyBuilder_ == null) {
          result.body_ = body_;
        } else {
          result.body_ = bodyBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While.getDefaultInstance()) return this;
        if (other.hasCondition()) {
          mergeCondition(other.getCondition());
        }
        if (other.hasBody()) {
          mergeBody(other.getBody());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasCondition()) {
          
          return false;
        }
        if (!hasBody()) {
          
          return false;
        }
        if (!getCondition().isInitialized()) {
          
          return false;
        }
        if (!getBody().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.While) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> conditionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public boolean hasCondition() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
        if (conditionBuilder_ == null) {
          return condition_;
        } else {
          return conditionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder setCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          condition_ = value;
          onChanged();
        } else {
          conditionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder setCondition(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (conditionBuilder_ == null) {
          condition_ = builderForValue.build();
          onChanged();
        } else {
          conditionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder mergeCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              condition_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            condition_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(condition_).mergeFrom(value).buildPartial();
          } else {
            condition_ = value;
          }
          onChanged();
        } else {
          conditionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder clearCondition() {
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getConditionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getConditionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
        if (conditionBuilder_ != null) {
          return conditionBuilder_.getMessageOrBuilder();
        } else {
          return condition_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getConditionFieldBuilder() {
        if (conditionBuilder_ == null) {
          conditionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getCondition(),
                  getParentForChildren(),
                  isClean());
          condition_ = null;
        }
        return conditionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> bodyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public boolean hasBody() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
        if (bodyBuilder_ == null) {
          return body_;
        } else {
          return bodyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder setBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          body_ = value;
          onChanged();
        } else {
          bodyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder setBody(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (bodyBuilder_ == null) {
          body_ = builderForValue.build();
          onChanged();
        } else {
          bodyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder mergeBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              body_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            body_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(body_).mergeFrom(value).buildPartial();
          } else {
            body_ = value;
          }
          onChanged();
        } else {
          bodyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder clearBody() {
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getBodyBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getBodyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
        if (bodyBuilder_ != null) {
          return bodyBuilder_.getMessageOrBuilder();
        } else {
          return body_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getBodyFieldBuilder() {
        if (bodyBuilder_ == null) {
          bodyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getBody(),
                  getParentForChildren(),
                  isClean());
          body_ = null;
        }
        return bodyBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.While)
    }

    static {
      defaultInstance = new While(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.While)
  }

  public interface DoWhileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.DoWhile)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    boolean hasCondition();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    boolean hasBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.DoWhile}
   */
  public static final class DoWhile extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.DoWhile)
      DoWhileOrBuilder {
    // Use DoWhile.newBuilder() to construct.
    private DoWhile(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private DoWhile(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final DoWhile defaultInstance;
    public static DoWhile getDefaultInstance() {
      return defaultInstance;
    }

    public DoWhile getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private DoWhile(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = condition_.toBuilder();
              }
              condition_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(condition_);
                condition_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = body_.toBuilder();
              }
              body_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(body_);
                body_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<DoWhile> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<DoWhile>() {
      public DoWhile parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new DoWhile(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<DoWhile> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int CONDITION_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public boolean hasCondition() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
      return condition_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
      return condition_;
    }

    public static final int BODY_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public boolean hasBody() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
      return body_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
      return body_;
    }

    private void initFields() {
      condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasCondition()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasBody()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getCondition().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getBody().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, condition_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, body_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, condition_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, body_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.DoWhile}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.DoWhile)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhileOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getConditionFieldBuilder();
          getBodyFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (conditionBuilder_ == null) {
          result.condition_ = condition_;
        } else {
          result.condition_ = conditionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (bodyBuilder_ == null) {
          result.body_ = body_;
        } else {
          result.body_ = bodyBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile.getDefaultInstance()) return this;
        if (other.hasCondition()) {
          mergeCondition(other.getCondition());
        }
        if (other.hasBody()) {
          mergeBody(other.getBody());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasCondition()) {
          
          return false;
        }
        if (!hasBody()) {
          
          return false;
        }
        if (!getCondition().isInitialized()) {
          
          return false;
        }
        if (!getBody().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.DoWhile) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> conditionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public boolean hasCondition() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
        if (conditionBuilder_ == null) {
          return condition_;
        } else {
          return conditionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder setCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          condition_ = value;
          onChanged();
        } else {
          conditionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder setCondition(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (conditionBuilder_ == null) {
          condition_ = builderForValue.build();
          onChanged();
        } else {
          conditionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder mergeCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              condition_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            condition_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(condition_).mergeFrom(value).buildPartial();
          } else {
            condition_ = value;
          }
          onChanged();
        } else {
          conditionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public Builder clearCondition() {
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getConditionBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getConditionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
        if (conditionBuilder_ != null) {
          return conditionBuilder_.getMessageOrBuilder();
        } else {
          return condition_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getConditionFieldBuilder() {
        if (conditionBuilder_ == null) {
          conditionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getCondition(),
                  getParentForChildren(),
                  isClean());
          condition_ = null;
        }
        return conditionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> bodyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public boolean hasBody() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
        if (bodyBuilder_ == null) {
          return body_;
        } else {
          return bodyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder setBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          body_ = value;
          onChanged();
        } else {
          bodyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder setBody(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (bodyBuilder_ == null) {
          body_ = builderForValue.build();
          onChanged();
        } else {
          bodyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder mergeBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              body_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            body_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(body_).mergeFrom(value).buildPartial();
          } else {
            body_ = value;
          }
          onChanged();
        } else {
          bodyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder clearBody() {
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getBodyBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getBodyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
        if (bodyBuilder_ != null) {
          return bodyBuilder_.getMessageOrBuilder();
        } else {
          return body_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getBodyFieldBuilder() {
        if (bodyBuilder_ == null) {
          bodyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getBody(),
                  getParentForChildren(),
                  isClean());
          body_ = null;
        }
        return bodyBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.DoWhile)
    }

    static {
      defaultInstance = new DoWhile(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.DoWhile)
  }

  public interface ForOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.For)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
     */
    boolean hasVariables();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getVariables();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getVariablesOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    boolean hasExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
     */
    boolean hasEmpty();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit getEmpty();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder getEmptyOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
     */
    boolean hasCondition();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
     */
    boolean hasIncrement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIncrement();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIncrementOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
     */
    boolean hasBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.For}
   */
  public static final class For extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.For)
      ForOrBuilder {
    // Use For.newBuilder() to construct.
    private For(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private For(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final For defaultInstance;
    public static For getDefaultInstance() {
      return defaultInstance;
    }

    public For getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private For(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (initCase_ == 1) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_).toBuilder();
              }
              init_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_);
                init_ = subBuilder.buildPartial();
              }
              initCase_ = 1;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (initCase_ == 2) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_).toBuilder();
              }
              init_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_);
                init_ = subBuilder.buildPartial();
              }
              initCase_ = 2;
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder subBuilder = null;
              if (initCase_ == 3) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_).toBuilder();
              }
              init_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_);
                init_ = subBuilder.buildPartial();
              }
              initCase_ = 3;
              break;
            }
            case 34: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = condition_.toBuilder();
              }
              condition_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(condition_);
                condition_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
            case 42: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000010) == 0x00000010)) {
                subBuilder = increment_.toBuilder();
              }
              increment_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(increment_);
                increment_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000010;
              break;
            }
            case 50: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000020) == 0x00000020)) {
                subBuilder = body_.toBuilder();
              }
              body_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(body_);
                body_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000020;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_For_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_For_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<For> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<For>() {
      public For parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new For(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<For> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    private int initCase_ = 0;
    private java.lang.Object init_;
    public enum InitCase
        implements org.jetbrains.kotlin.protobuf.Internal.EnumLite {
      VARIABLES(1),
      EXPRESSION(2),
      EMPTY(3),
      INIT_NOT_SET(0);
      private int value = 0;
      private InitCase(int value) {
        this.value = value;
      }
      public static InitCase valueOf(int value) {
        switch (value) {
          case 1: return VARIABLES;
          case 2: return EXPRESSION;
          case 3: return EMPTY;
          case 0: return INIT_NOT_SET;
          default: throw new java.lang.IllegalArgumentException(
            "Value is undefined for this oneof enum.");
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public InitCase
    getInitCase() {
      return InitCase.valueOf(
          initCase_);
    }

    public static final int VARIABLES_FIELD_NUMBER = 1;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
     */
    public boolean hasVariables() {
      return initCase_ == 1;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getVariables() {
      if (initCase_ == 1) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getVariablesOrBuilder() {
      if (initCase_ == 1) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }

    public static final int EXPRESSION_FIELD_NUMBER = 2;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public boolean hasExpression() {
      return initCase_ == 2;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
      if (initCase_ == 2) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
      if (initCase_ == 2) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }

    public static final int EMPTY_FIELD_NUMBER = 3;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
     */
    public boolean hasEmpty() {
      return initCase_ == 3;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit getEmpty() {
      if (initCase_ == 3) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder getEmptyOrBuilder() {
      if (initCase_ == 3) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
    }

    public static final int CONDITION_FIELD_NUMBER = 4;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
     */
    public boolean hasCondition() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
      return condition_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
      return condition_;
    }

    public static final int INCREMENT_FIELD_NUMBER = 5;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression increment_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
     */
    public boolean hasIncrement() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIncrement() {
      return increment_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIncrementOrBuilder() {
      return increment_;
    }

    public static final int BODY_FIELD_NUMBER = 6;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
     */
    public boolean hasBody() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
      return body_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
      return body_;
    }

    private void initFields() {
      condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      increment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasBody()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasVariables()) {
        if (!getVariables().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasExpression()) {
        if (!getExpression().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasCondition()) {
        if (!getCondition().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasIncrement()) {
        if (!getIncrement().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (!getBody().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (initCase_ == 1) {
        output.writeMessage(1, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_);
      }
      if (initCase_ == 2) {
        output.writeMessage(2, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_);
      }
      if (initCase_ == 3) {
        output.writeMessage(3, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, condition_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeMessage(5, increment_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeMessage(6, body_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (initCase_ == 1) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_);
      }
      if (initCase_ == 2) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_);
      }
      if (initCase_ == 3) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(4, condition_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(5, increment_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(6, body_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.For}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.For)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_For_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_For_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getConditionFieldBuilder();
          getIncrementFieldBuilder();
          getBodyFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        if (incrementBuilder_ == null) {
          increment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          incrementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000020);
        initCase_ = 0;
        init_ = null;
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_For_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (initCase_ == 1) {
          if (variablesBuilder_ == null) {
            result.init_ = init_;
          } else {
            result.init_ = variablesBuilder_.build();
          }
        }
        if (initCase_ == 2) {
          if (expressionBuilder_ == null) {
            result.init_ = init_;
          } else {
            result.init_ = expressionBuilder_.build();
          }
        }
        if (initCase_ == 3) {
          if (emptyBuilder_ == null) {
            result.init_ = init_;
          } else {
            result.init_ = emptyBuilder_.build();
          }
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (conditionBuilder_ == null) {
          result.condition_ = condition_;
        } else {
          result.condition_ = conditionBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        if (incrementBuilder_ == null) {
          result.increment_ = increment_;
        } else {
          result.increment_ = incrementBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        if (bodyBuilder_ == null) {
          result.body_ = body_;
        } else {
          result.body_ = bodyBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        result.initCase_ = initCase_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For.getDefaultInstance()) return this;
        if (other.hasCondition()) {
          mergeCondition(other.getCondition());
        }
        if (other.hasIncrement()) {
          mergeIncrement(other.getIncrement());
        }
        if (other.hasBody()) {
          mergeBody(other.getBody());
        }
        switch (other.getInitCase()) {
          case VARIABLES: {
            mergeVariables(other.getVariables());
            break;
          }
          case EXPRESSION: {
            mergeExpression(other.getExpression());
            break;
          }
          case EMPTY: {
            mergeEmpty(other.getEmpty());
            break;
          }
          case INIT_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasBody()) {
          
          return false;
        }
        if (hasVariables()) {
          if (!getVariables().isInitialized()) {
            
            return false;
          }
        }
        if (hasExpression()) {
          if (!getExpression().isInitialized()) {
            
            return false;
          }
        }
        if (hasCondition()) {
          if (!getCondition().isInitialized()) {
            
            return false;
          }
        }
        if (hasIncrement()) {
          if (!getIncrement().isInitialized()) {
            
            return false;
          }
        }
        if (!getBody().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.For) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int initCase_ = 0;
      private java.lang.Object init_;
      public InitCase
          getInitCase() {
        return InitCase.valueOf(
            initCase_);
      }

      public Builder clearInit() {
        initCase_ = 0;
        init_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> variablesBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public boolean hasVariables() {
        return initCase_ == 1;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getVariables() {
        if (variablesBuilder_ == null) {
          if (initCase_ == 1) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          if (initCase_ == 1) {
            return variablesBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public Builder setVariables(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (variablesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          init_ = value;
          onChanged();
        } else {
          variablesBuilder_.setMessage(value);
        }
        initCase_ = 1;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public Builder setVariables(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (variablesBuilder_ == null) {
          init_ = builderForValue.build();
          onChanged();
        } else {
          variablesBuilder_.setMessage(builderForValue.build());
        }
        initCase_ = 1;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public Builder mergeVariables(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (variablesBuilder_ == null) {
          if (initCase_ == 1 &&
              init_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            init_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_)
                .mergeFrom(value).buildPartial();
          } else {
            init_ = value;
          }
          onChanged();
        } else {
          if (initCase_ == 1) {
            variablesBuilder_.mergeFrom(value);
          }
          variablesBuilder_.setMessage(value);
        }
        initCase_ = 1;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public Builder clearVariables() {
        if (variablesBuilder_ == null) {
          if (initCase_ == 1) {
            initCase_ = 0;
            init_ = null;
            onChanged();
          }
        } else {
          if (initCase_ == 1) {
            initCase_ = 0;
            init_ = null;
          }
          variablesBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getVariablesBuilder() {
        return getVariablesFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getVariablesOrBuilder() {
        if ((initCase_ == 1) && (variablesBuilder_ != null)) {
          return variablesBuilder_.getMessageOrBuilder();
        } else {
          if (initCase_ == 1) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement variables = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getVariablesFieldBuilder() {
        if (variablesBuilder_ == null) {
          if (!(initCase_ == 1)) {
            init_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          }
          variablesBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement) init_,
                  getParentForChildren(),
                  isClean());
          init_ = null;
        }
        initCase_ = 1;
        return variablesBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> expressionBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public boolean hasExpression() {
        return initCase_ == 2;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
        if (expressionBuilder_ == null) {
          if (initCase_ == 2) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          if (initCase_ == 2) {
            return expressionBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          init_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        initCase_ = 2;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          init_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        initCase_ = 2;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (initCase_ == 2 &&
              init_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            init_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_)
                .mergeFrom(value).buildPartial();
          } else {
            init_ = value;
          }
          onChanged();
        } else {
          if (initCase_ == 2) {
            expressionBuilder_.mergeFrom(value);
          }
          expressionBuilder_.setMessage(value);
        }
        initCase_ = 2;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          if (initCase_ == 2) {
            initCase_ = 0;
            init_ = null;
            onChanged();
          }
        } else {
          if (initCase_ == 2) {
            initCase_ = 0;
            init_ = null;
          }
          expressionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExpressionBuilder() {
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
        if ((initCase_ == 2) && (expressionBuilder_ != null)) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          if (initCase_ == 2) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          if (!(initCase_ == 2)) {
            init_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          }
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) init_,
                  getParentForChildren(),
                  isClean());
          init_ = null;
        }
        initCase_ = 2;
        return expressionBuilder_;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder> emptyBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public boolean hasEmpty() {
        return initCase_ == 3;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit getEmpty() {
        if (emptyBuilder_ == null) {
          if (initCase_ == 3) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
        } else {
          if (initCase_ == 3) {
            return emptyBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public Builder setEmpty(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit value) {
        if (emptyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          init_ = value;
          onChanged();
        } else {
          emptyBuilder_.setMessage(value);
        }
        initCase_ = 3;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public Builder setEmpty(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder builderForValue) {
        if (emptyBuilder_ == null) {
          init_ = builderForValue.build();
          onChanged();
        } else {
          emptyBuilder_.setMessage(builderForValue.build());
        }
        initCase_ = 3;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public Builder mergeEmpty(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit value) {
        if (emptyBuilder_ == null) {
          if (initCase_ == 3 &&
              init_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance()) {
            init_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_)
                .mergeFrom(value).buildPartial();
          } else {
            init_ = value;
          }
          onChanged();
        } else {
          if (initCase_ == 3) {
            emptyBuilder_.mergeFrom(value);
          }
          emptyBuilder_.setMessage(value);
        }
        initCase_ = 3;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public Builder clearEmpty() {
        if (emptyBuilder_ == null) {
          if (initCase_ == 3) {
            initCase_ = 0;
            init_ = null;
            onChanged();
          }
        } else {
          if (initCase_ == 3) {
            initCase_ = 0;
            init_ = null;
          }
          emptyBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder getEmptyBuilder() {
        return getEmptyFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder getEmptyOrBuilder() {
        if ((initCase_ == 3) && (emptyBuilder_ != null)) {
          return emptyBuilder_.getMessageOrBuilder();
        } else {
          if (initCase_ == 3) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.EmptyInit empty = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder> 
          getEmptyFieldBuilder() {
        if (emptyBuilder_ == null) {
          if (!(initCase_ == 3)) {
            init_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
          }
          emptyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) init_,
                  getParentForChildren(),
                  isClean());
          init_ = null;
        }
        initCase_ = 3;
        return emptyBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> conditionBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public boolean hasCondition() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getCondition() {
        if (conditionBuilder_ == null) {
          return condition_;
        } else {
          return conditionBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public Builder setCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          condition_ = value;
          onChanged();
        } else {
          conditionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public Builder setCondition(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (conditionBuilder_ == null) {
          condition_ = builderForValue.build();
          onChanged();
        } else {
          conditionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public Builder mergeCondition(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (conditionBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              condition_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            condition_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(condition_).mergeFrom(value).buildPartial();
          } else {
            condition_ = value;
          }
          onChanged();
        } else {
          conditionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public Builder clearCondition() {
        if (conditionBuilder_ == null) {
          condition_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          conditionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getConditionBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getConditionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getConditionOrBuilder() {
        if (conditionBuilder_ != null) {
          return conditionBuilder_.getMessageOrBuilder();
        } else {
          return condition_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression condition = 4;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getConditionFieldBuilder() {
        if (conditionBuilder_ == null) {
          conditionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getCondition(),
                  getParentForChildren(),
                  isClean());
          condition_ = null;
        }
        return conditionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression increment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> incrementBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public boolean hasIncrement() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIncrement() {
        if (incrementBuilder_ == null) {
          return increment_;
        } else {
          return incrementBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public Builder setIncrement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (incrementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          increment_ = value;
          onChanged();
        } else {
          incrementBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public Builder setIncrement(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (incrementBuilder_ == null) {
          increment_ = builderForValue.build();
          onChanged();
        } else {
          incrementBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public Builder mergeIncrement(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (incrementBuilder_ == null) {
          if (((bitField0_ & 0x00000010) == 0x00000010) &&
              increment_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            increment_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(increment_).mergeFrom(value).buildPartial();
          } else {
            increment_ = value;
          }
          onChanged();
        } else {
          incrementBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public Builder clearIncrement() {
        if (incrementBuilder_ == null) {
          increment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          incrementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getIncrementBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getIncrementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIncrementOrBuilder() {
        if (incrementBuilder_ != null) {
          return incrementBuilder_.getMessageOrBuilder();
        } else {
          return increment_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression increment = 5;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getIncrementFieldBuilder() {
        if (incrementBuilder_ == null) {
          incrementBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getIncrement(),
                  getParentForChildren(),
                  isClean());
          increment_ = null;
        }
        return incrementBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> bodyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public boolean hasBody() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
        if (bodyBuilder_ == null) {
          return body_;
        } else {
          return bodyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public Builder setBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          body_ = value;
          onChanged();
        } else {
          bodyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000020;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public Builder setBody(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (bodyBuilder_ == null) {
          body_ = builderForValue.build();
          onChanged();
        } else {
          bodyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000020;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public Builder mergeBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (((bitField0_ & 0x00000020) == 0x00000020) &&
              body_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            body_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(body_).mergeFrom(value).buildPartial();
          } else {
            body_ = value;
          }
          onChanged();
        } else {
          bodyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000020;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public Builder clearBody() {
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getBodyBuilder() {
        bitField0_ |= 0x00000020;
        onChanged();
        return getBodyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
        if (bodyBuilder_ != null) {
          return bodyBuilder_.getMessageOrBuilder();
        } else {
          return body_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 6;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getBodyFieldBuilder() {
        if (bodyBuilder_ == null) {
          bodyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getBody(),
                  getParentForChildren(),
                  isClean());
          body_ = null;
        }
        return bodyBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.For)
    }

    static {
      defaultInstance = new For(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.For)
  }

  public interface EmptyInitOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.EmptyInit)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.EmptyInit}
   */
  public static final class EmptyInit extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.EmptyInit)
      EmptyInitOrBuilder {
    // Use EmptyInit.newBuilder() to construct.
    private EmptyInit(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private EmptyInit(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final EmptyInit defaultInstance;
    public static EmptyInit getDefaultInstance() {
      return defaultInstance;
    }

    public EmptyInit getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private EmptyInit(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<EmptyInit> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<EmptyInit>() {
      public EmptyInit parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new EmptyInit(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<EmptyInit> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.EmptyInit}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.EmptyInit)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInitOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyInit) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.EmptyInit)
    }

    static {
      defaultInstance = new EmptyInit(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.EmptyInit)
  }

  public interface ForInOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ForIn)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 nameId = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>optional int32 nameId = 1;</code>
     */
    int getNameId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    boolean hasExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
     */
    boolean hasIterable();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIterable();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIterableOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
     */
    boolean hasBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ForIn}
   */
  public static final class ForIn extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ForIn)
      ForInOrBuilder {
    // Use ForIn.newBuilder() to construct.
    private ForIn(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ForIn(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ForIn defaultInstance;
    public static ForIn getDefaultInstance() {
      return defaultInstance;
    }

    public ForIn getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ForIn(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              valueCase_ = 1;
              value_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (valueCase_ == 2) {
                subBuilder = ((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_).toBuilder();
              }
              value_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_);
                value_ = subBuilder.buildPartial();
              }
              valueCase_ = 2;
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = iterable_.toBuilder();
              }
              iterable_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(iterable_);
                iterable_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
            case 34: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000008) == 0x00000008)) {
                subBuilder = body_.toBuilder();
              }
              body_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(body_);
                body_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000008;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ForIn> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ForIn>() {
      public ForIn parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ForIn(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ForIn> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    private int valueCase_ = 0;
    private java.lang.Object value_;
    public enum ValueCase
        implements org.jetbrains.kotlin.protobuf.Internal.EnumLite {
      NAMEID(1),
      EXPRESSION(2),
      VALUE_NOT_SET(0);
      private int value = 0;
      private ValueCase(int value) {
        this.value = value;
      }
      public static ValueCase valueOf(int value) {
        switch (value) {
          case 1: return NAMEID;
          case 2: return EXPRESSION;
          case 0: return VALUE_NOT_SET;
          default: throw new java.lang.IllegalArgumentException(
            "Value is undefined for this oneof enum.");
        }
      }
      public int getNumber() {
        return this.value;
      }
    };

    public ValueCase
    getValueCase() {
      return ValueCase.valueOf(
          valueCase_);
    }

    public static final int NAMEID_FIELD_NUMBER = 1;
    /**
     * <code>optional int32 nameId = 1;</code>
     */
    public boolean hasNameId() {
      return valueCase_ == 1;
    }
    /**
     * <code>optional int32 nameId = 1;</code>
     */
    public int getNameId() {
      if (valueCase_ == 1) {
        return (java.lang.Integer) value_;
      }
      return 0;
    }

    public static final int EXPRESSION_FIELD_NUMBER = 2;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public boolean hasExpression() {
      return valueCase_ == 2;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
      if (valueCase_ == 2) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
      if (valueCase_ == 2) {
         return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
      }
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }

    public static final int ITERABLE_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression iterable_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
     */
    public boolean hasIterable() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIterable() {
      return iterable_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIterableOrBuilder() {
      return iterable_;
    }

    public static final int BODY_FIELD_NUMBER = 4;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
     */
    public boolean hasBody() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
      return body_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
      return body_;
    }

    private void initFields() {
      iterable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasIterable()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasBody()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasExpression()) {
        if (!getExpression().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (!getIterable().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getBody().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (valueCase_ == 1) {
        output.writeInt32(
            1, (int)((java.lang.Integer) value_));
      }
      if (valueCase_ == 2) {
        output.writeMessage(2, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, iterable_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeMessage(4, body_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (valueCase_ == 1) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(
              1, (int)((java.lang.Integer) value_));
      }
      if (valueCase_ == 2) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, iterable_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(4, body_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ForIn}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ForIn)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForInOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getIterableFieldBuilder();
          getBodyFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (iterableBuilder_ == null) {
          iterable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          iterableBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        valueCase_ = 0;
        value_ = null;
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (valueCase_ == 1) {
          result.value_ = value_;
        }
        if (valueCase_ == 2) {
          if (expressionBuilder_ == null) {
            result.value_ = value_;
          } else {
            result.value_ = expressionBuilder_.build();
          }
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (iterableBuilder_ == null) {
          result.iterable_ = iterable_;
        } else {
          result.iterable_ = iterableBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        if (bodyBuilder_ == null) {
          result.body_ = body_;
        } else {
          result.body_ = bodyBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        result.valueCase_ = valueCase_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn.getDefaultInstance()) return this;
        if (other.hasIterable()) {
          mergeIterable(other.getIterable());
        }
        if (other.hasBody()) {
          mergeBody(other.getBody());
        }
        switch (other.getValueCase()) {
          case NAMEID: {
            setNameId(other.getNameId());
            break;
          }
          case EXPRESSION: {
            mergeExpression(other.getExpression());
            break;
          }
          case VALUE_NOT_SET: {
            break;
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasIterable()) {
          
          return false;
        }
        if (!hasBody()) {
          
          return false;
        }
        if (hasExpression()) {
          if (!getExpression().isInitialized()) {
            
            return false;
          }
        }
        if (!getIterable().isInitialized()) {
          
          return false;
        }
        if (!getBody().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ForIn) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int valueCase_ = 0;
      private java.lang.Object value_;
      public ValueCase
          getValueCase() {
        return ValueCase.valueOf(
            valueCase_);
      }

      public Builder clearValue() {
        valueCase_ = 0;
        value_ = null;
        onChanged();
        return this;
      }

      private int bitField0_;

      /**
       * <code>optional int32 nameId = 1;</code>
       */
      public boolean hasNameId() {
        return valueCase_ == 1;
      }
      /**
       * <code>optional int32 nameId = 1;</code>
       */
      public int getNameId() {
        if (valueCase_ == 1) {
          return (java.lang.Integer) value_;
        }
        return 0;
      }
      /**
       * <code>optional int32 nameId = 1;</code>
       */
      public Builder setNameId(int value) {
        valueCase_ = 1;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 nameId = 1;</code>
       */
      public Builder clearNameId() {
        if (valueCase_ == 1) {
          valueCase_ = 0;
          value_ = null;
          onChanged();
        }
        return this;
      }

      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> expressionBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public boolean hasExpression() {
        return valueCase_ == 2;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
        if (expressionBuilder_ == null) {
          if (valueCase_ == 2) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          if (valueCase_ == 2) {
            return expressionBuilder_.getMessage();
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          value_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        valueCase_ = 2;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          value_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        valueCase_ = 2;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (valueCase_ == 2 &&
              value_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_)
                .mergeFrom(value).buildPartial();
          } else {
            value_ = value;
          }
          onChanged();
        } else {
          if (valueCase_ == 2) {
            expressionBuilder_.mergeFrom(value);
          }
          expressionBuilder_.setMessage(value);
        }
        valueCase_ = 2;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          if (valueCase_ == 2) {
            valueCase_ = 0;
            value_ = null;
            onChanged();
          }
        } else {
          if (valueCase_ == 2) {
            valueCase_ = 0;
            value_ = null;
          }
          expressionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExpressionBuilder() {
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
        if ((valueCase_ == 2) && (expressionBuilder_ != null)) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          if (valueCase_ == 2) {
            return (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_;
          }
          return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          if (!(valueCase_ == 2)) {
            value_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          }
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression) value_,
                  getParentForChildren(),
                  isClean());
          value_ = null;
        }
        valueCase_ = 2;
        return expressionBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression iterable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> iterableBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public boolean hasIterable() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getIterable() {
        if (iterableBuilder_ == null) {
          return iterable_;
        } else {
          return iterableBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public Builder setIterable(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (iterableBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          iterable_ = value;
          onChanged();
        } else {
          iterableBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public Builder setIterable(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (iterableBuilder_ == null) {
          iterable_ = builderForValue.build();
          onChanged();
        } else {
          iterableBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public Builder mergeIterable(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (iterableBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              iterable_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            iterable_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(iterable_).mergeFrom(value).buildPartial();
          } else {
            iterable_ = value;
          }
          onChanged();
        } else {
          iterableBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public Builder clearIterable() {
        if (iterableBuilder_ == null) {
          iterable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          iterableBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getIterableBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getIterableFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getIterableOrBuilder() {
        if (iterableBuilder_ != null) {
          return iterableBuilder_.getMessageOrBuilder();
        } else {
          return iterable_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression iterable = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getIterableFieldBuilder() {
        if (iterableBuilder_ == null) {
          iterableBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getIterable(),
                  getParentForChildren(),
                  isClean());
          iterable_ = null;
        }
        return iterableBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> bodyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public boolean hasBody() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
        if (bodyBuilder_ == null) {
          return body_;
        } else {
          return bodyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public Builder setBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          body_ = value;
          onChanged();
        } else {
          bodyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public Builder setBody(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (bodyBuilder_ == null) {
          body_ = builderForValue.build();
          onChanged();
        } else {
          bodyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public Builder mergeBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              body_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            body_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(body_).mergeFrom(value).buildPartial();
          } else {
            body_ = value;
          }
          onChanged();
        } else {
          bodyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public Builder clearBody() {
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getBodyBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getBodyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
        if (bodyBuilder_ != null) {
          return bodyBuilder_.getMessageOrBuilder();
        } else {
          return body_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 4;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getBodyFieldBuilder() {
        if (bodyBuilder_ == null) {
          bodyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getBody(),
                  getParentForChildren(),
                  isClean());
          body_ = null;
        }
        return bodyBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ForIn)
    }

    static {
      defaultInstance = new ForIn(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ForIn)
  }

  public interface TryOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Try)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
     */
    boolean hasTryBlock();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getTryBlock();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getTryBlockOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
     */
    boolean hasCatchBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch getCatchBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder getCatchBlockOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
     */
    boolean hasFinallyBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getFinallyBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getFinallyBlockOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Try}
   */
  public static final class Try extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Try)
      TryOrBuilder {
    // Use Try.newBuilder() to construct.
    private Try(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Try(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Try defaultInstance;
    public static Try getDefaultInstance() {
      return defaultInstance;
    }

    public Try getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Try(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = tryBlock_.toBuilder();
              }
              tryBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(tryBlock_);
                tryBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = catchBlock_.toBuilder();
              }
              catchBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(catchBlock_);
                catchBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = finallyBlock_.toBuilder();
              }
              finallyBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(finallyBlock_);
                finallyBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Try> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Try>() {
      public Try parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Try(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Try> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int TRYBLOCK_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement tryBlock_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
     */
    public boolean hasTryBlock() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getTryBlock() {
      return tryBlock_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getTryBlockOrBuilder() {
      return tryBlock_;
    }

    public static final int CATCHBLOCK_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch catchBlock_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
     */
    public boolean hasCatchBlock() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch getCatchBlock() {
      return catchBlock_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder getCatchBlockOrBuilder() {
      return catchBlock_;
    }

    public static final int FINALLYBLOCK_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement finallyBlock_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
     */
    public boolean hasFinallyBlock() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getFinallyBlock() {
      return finallyBlock_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getFinallyBlockOrBuilder() {
      return finallyBlock_;
    }

    private void initFields() {
      tryBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      catchBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance();
      finallyBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasTryBlock()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getTryBlock().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasCatchBlock()) {
        if (!getCatchBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasFinallyBlock()) {
        if (!getFinallyBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, tryBlock_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, catchBlock_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, finallyBlock_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, tryBlock_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, catchBlock_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, finallyBlock_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Try}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Try)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.TryOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getTryBlockFieldBuilder();
          getCatchBlockFieldBuilder();
          getFinallyBlockFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (tryBlockBuilder_ == null) {
          tryBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          tryBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (catchBlockBuilder_ == null) {
          catchBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance();
        } else {
          catchBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (finallyBlockBuilder_ == null) {
          finallyBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          finallyBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (tryBlockBuilder_ == null) {
          result.tryBlock_ = tryBlock_;
        } else {
          result.tryBlock_ = tryBlockBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (catchBlockBuilder_ == null) {
          result.catchBlock_ = catchBlock_;
        } else {
          result.catchBlock_ = catchBlockBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (finallyBlockBuilder_ == null) {
          result.finallyBlock_ = finallyBlock_;
        } else {
          result.finallyBlock_ = finallyBlockBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try.getDefaultInstance()) return this;
        if (other.hasTryBlock()) {
          mergeTryBlock(other.getTryBlock());
        }
        if (other.hasCatchBlock()) {
          mergeCatchBlock(other.getCatchBlock());
        }
        if (other.hasFinallyBlock()) {
          mergeFinallyBlock(other.getFinallyBlock());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTryBlock()) {
          
          return false;
        }
        if (!getTryBlock().isInitialized()) {
          
          return false;
        }
        if (hasCatchBlock()) {
          if (!getCatchBlock().isInitialized()) {
            
            return false;
          }
        }
        if (hasFinallyBlock()) {
          if (!getFinallyBlock().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Try) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement tryBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> tryBlockBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public boolean hasTryBlock() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getTryBlock() {
        if (tryBlockBuilder_ == null) {
          return tryBlock_;
        } else {
          return tryBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public Builder setTryBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (tryBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          tryBlock_ = value;
          onChanged();
        } else {
          tryBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public Builder setTryBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (tryBlockBuilder_ == null) {
          tryBlock_ = builderForValue.build();
          onChanged();
        } else {
          tryBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public Builder mergeTryBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (tryBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              tryBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            tryBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(tryBlock_).mergeFrom(value).buildPartial();
          } else {
            tryBlock_ = value;
          }
          onChanged();
        } else {
          tryBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public Builder clearTryBlock() {
        if (tryBlockBuilder_ == null) {
          tryBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          tryBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getTryBlockBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getTryBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getTryBlockOrBuilder() {
        if (tryBlockBuilder_ != null) {
          return tryBlockBuilder_.getMessageOrBuilder();
        } else {
          return tryBlock_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement tryBlock = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getTryBlockFieldBuilder() {
        if (tryBlockBuilder_ == null) {
          tryBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getTryBlock(),
                  getParentForChildren(),
                  isClean());
          tryBlock_ = null;
        }
        return tryBlockBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch catchBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder> catchBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public boolean hasCatchBlock() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch getCatchBlock() {
        if (catchBlockBuilder_ == null) {
          return catchBlock_;
        } else {
          return catchBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public Builder setCatchBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch value) {
        if (catchBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          catchBlock_ = value;
          onChanged();
        } else {
          catchBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public Builder setCatchBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder builderForValue) {
        if (catchBlockBuilder_ == null) {
          catchBlock_ = builderForValue.build();
          onChanged();
        } else {
          catchBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public Builder mergeCatchBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch value) {
        if (catchBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              catchBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance()) {
            catchBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.newBuilder(catchBlock_).mergeFrom(value).buildPartial();
          } else {
            catchBlock_ = value;
          }
          onChanged();
        } else {
          catchBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public Builder clearCatchBlock() {
        if (catchBlockBuilder_ == null) {
          catchBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance();
          onChanged();
        } else {
          catchBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder getCatchBlockBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getCatchBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder getCatchBlockOrBuilder() {
        if (catchBlockBuilder_ != null) {
          return catchBlockBuilder_.getMessageOrBuilder();
        } else {
          return catchBlock_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Catch catchBlock = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder> 
          getCatchBlockFieldBuilder() {
        if (catchBlockBuilder_ == null) {
          catchBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder>(
                  getCatchBlock(),
                  getParentForChildren(),
                  isClean());
          catchBlock_ = null;
        }
        return catchBlockBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement finallyBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> finallyBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public boolean hasFinallyBlock() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getFinallyBlock() {
        if (finallyBlockBuilder_ == null) {
          return finallyBlock_;
        } else {
          return finallyBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public Builder setFinallyBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (finallyBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          finallyBlock_ = value;
          onChanged();
        } else {
          finallyBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public Builder setFinallyBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (finallyBlockBuilder_ == null) {
          finallyBlock_ = builderForValue.build();
          onChanged();
        } else {
          finallyBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public Builder mergeFinallyBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (finallyBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              finallyBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            finallyBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(finallyBlock_).mergeFrom(value).buildPartial();
          } else {
            finallyBlock_ = value;
          }
          onChanged();
        } else {
          finallyBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public Builder clearFinallyBlock() {
        if (finallyBlockBuilder_ == null) {
          finallyBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          finallyBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getFinallyBlockBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getFinallyBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getFinallyBlockOrBuilder() {
        if (finallyBlockBuilder_ != null) {
          return finallyBlockBuilder_.getMessageOrBuilder();
        } else {
          return finallyBlock_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Statement finallyBlock = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getFinallyBlockFieldBuilder() {
        if (finallyBlockBuilder_ == null) {
          finallyBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getFinallyBlock(),
                  getParentForChildren(),
                  isClean());
          finallyBlock_ = null;
        }
        return finallyBlockBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Try)
    }

    static {
      defaultInstance = new Try(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Try)
  }

  public interface CatchOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Catch)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    boolean hasParameter();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getParameter();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder getParameterOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    boolean hasBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Catch}
   */
  public static final class Catch extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Catch)
      CatchOrBuilder {
    // Use Catch.newBuilder() to construct.
    private Catch(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Catch(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Catch defaultInstance;
    public static Catch getDefaultInstance() {
      return defaultInstance;
    }

    public Catch getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Catch(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = parameter_.toBuilder();
              }
              parameter_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(parameter_);
                parameter_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = body_.toBuilder();
              }
              body_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(body_);
                body_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Catch> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Catch>() {
      public Catch parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Catch(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Catch> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int PARAMETER_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parameter_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public boolean hasParameter() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getParameter() {
      return parameter_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder getParameterOrBuilder() {
      return parameter_;
    }

    public static final int BODY_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public boolean hasBody() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
      return body_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
      return body_;
    }

    private void initFields() {
      parameter_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance();
      body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasParameter()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasBody()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getParameter().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getBody().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, parameter_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, body_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, parameter_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, body_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Catch}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Catch)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.CatchOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getParameterFieldBuilder();
          getBodyFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (parameterBuilder_ == null) {
          parameter_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance();
        } else {
          parameterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (parameterBuilder_ == null) {
          result.parameter_ = parameter_;
        } else {
          result.parameter_ = parameterBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (bodyBuilder_ == null) {
          result.body_ = body_;
        } else {
          result.body_ = bodyBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch.getDefaultInstance()) return this;
        if (other.hasParameter()) {
          mergeParameter(other.getParameter());
        }
        if (other.hasBody()) {
          mergeBody(other.getBody());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasParameter()) {
          
          return false;
        }
        if (!hasBody()) {
          
          return false;
        }
        if (!getParameter().isInitialized()) {
          
          return false;
        }
        if (!getBody().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Catch) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter parameter_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> parameterBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public boolean hasParameter() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter getParameter() {
        if (parameterBuilder_ == null) {
          return parameter_;
        } else {
          return parameterBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder setParameter(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter value) {
        if (parameterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          parameter_ = value;
          onChanged();
        } else {
          parameterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder setParameter(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder builderForValue) {
        if (parameterBuilder_ == null) {
          parameter_ = builderForValue.build();
          onChanged();
        } else {
          parameterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder mergeParameter(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter value) {
        if (parameterBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              parameter_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance()) {
            parameter_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.newBuilder(parameter_).mergeFrom(value).buildPartial();
          } else {
            parameter_ = value;
          }
          onChanged();
        } else {
          parameterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public Builder clearParameter() {
        if (parameterBuilder_ == null) {
          parameter_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.getDefaultInstance();
          onChanged();
        } else {
          parameterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder getParameterBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getParameterFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder getParameterOrBuilder() {
        if (parameterBuilder_ != null) {
          return parameterBuilder_.getMessageOrBuilder();
        } else {
          return parameter_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Parameter parameter = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder> 
          getParameterFieldBuilder() {
        if (parameterBuilder_ == null) {
          parameterBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Parameter.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ParameterOrBuilder>(
                  getParameter(),
                  getParentForChildren(),
                  isClean());
          parameter_ = null;
        }
        return parameterBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> bodyBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public boolean hasBody() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement getBody() {
        if (bodyBuilder_ == null) {
          return body_;
        } else {
          return bodyBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder setBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          body_ = value;
          onChanged();
        } else {
          bodyBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder setBody(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder builderForValue) {
        if (bodyBuilder_ == null) {
          body_ = builderForValue.build();
          onChanged();
        } else {
          bodyBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder mergeBody(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement value) {
        if (bodyBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              body_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance()) {
            body_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.newBuilder(body_).mergeFrom(value).buildPartial();
          } else {
            body_ = value;
          }
          onChanged();
        } else {
          bodyBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public Builder clearBody() {
        if (bodyBuilder_ == null) {
          body_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.getDefaultInstance();
          onChanged();
        } else {
          bodyBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder getBodyBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getBodyFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder getBodyOrBuilder() {
        if (bodyBuilder_ != null) {
          return bodyBuilder_.getMessageOrBuilder();
        } else {
          return body_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Statement body = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder> 
          getBodyFieldBuilder() {
        if (bodyBuilder_ == null) {
          bodyBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Statement.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StatementOrBuilder>(
                  getBody(),
                  getParentForChildren(),
                  isClean());
          body_ = null;
        }
        return bodyBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Catch)
    }

    static {
      defaultInstance = new Catch(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Catch)
  }

  public interface EmptyOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Empty)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Empty}
   */
  public static final class Empty extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Empty)
      EmptyOrBuilder {
    // Use Empty.newBuilder() to construct.
    private Empty(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Empty(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Empty defaultInstance;
    public static Empty getDefaultInstance() {
      return defaultInstance;
    }

    public Empty getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Empty(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Empty> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Empty>() {
      public Empty parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Empty(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Empty> getParserForType() {
      return PARSER;
    }

    private void initFields() {
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Empty}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Empty)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.EmptyOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty(this);
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Empty) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Empty)
    }

    static {
      defaultInstance = new Empty(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Empty)
  }

  public interface FragmentOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Fragment)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule> 
        getImportedModuleList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule getImportedModule(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    int getImportedModuleCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder> 
        getImportedModuleOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder getImportedModuleOrBuilder(
        int index);

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import> 
        getImportEntryList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import getImportEntry(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    int getImportEntryCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder> 
        getImportEntryOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder getImportEntryOrBuilder(
        int index);

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
     */
    boolean hasDeclarationBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getDeclarationBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getDeclarationBlockOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
     */
    boolean hasExportBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getExportBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getExportBlockOrBuilder();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
     */
    boolean hasInitializerBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getInitializerBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getInitializerBlockOrBuilder();

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding> 
        getNameBindingList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding getNameBinding(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    int getNameBindingCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder> 
        getNameBindingOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder getNameBindingOrBuilder(
        int index);

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel> 
        getClassModelList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel getClassModel(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    int getClassModelCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder> 
        getClassModelOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder getClassModelOrBuilder(
        int index);

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> 
        getModuleExpressionList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getModuleExpression(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    int getModuleExpressionCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getModuleExpressionOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getModuleExpressionOrBuilder(
        int index);

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule> 
        getInlineModuleList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule getInlineModule(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    int getInlineModuleCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder> 
        getInlineModuleOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder getInlineModuleOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Fragment}
   */
  public static final class Fragment extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Fragment)
      FragmentOrBuilder {
    // Use Fragment.newBuilder() to construct.
    private Fragment(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Fragment(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Fragment defaultInstance;
    public static Fragment getDefaultInstance() {
      return defaultInstance;
    }

    public Fragment getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Fragment(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                importedModule_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule>();
                mutable_bitField0_ |= 0x00000001;
              }
              importedModule_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.PARSER, extensionRegistry));
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                importEntry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import>();
                mutable_bitField0_ |= 0x00000002;
              }
              importEntry_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.PARSER, extensionRegistry));
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = declarationBlock_.toBuilder();
              }
              declarationBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(declarationBlock_);
                declarationBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 34: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = exportBlock_.toBuilder();
              }
              exportBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(exportBlock_);
                exportBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 42: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = initializerBlock_.toBuilder();
              }
              initializerBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(initializerBlock_);
                initializerBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
            case 50: {
              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
                nameBinding_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding>();
                mutable_bitField0_ |= 0x00000020;
              }
              nameBinding_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.PARSER, extensionRegistry));
              break;
            }
            case 58: {
              if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
                classModel_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel>();
                mutable_bitField0_ |= 0x00000040;
              }
              classModel_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.PARSER, extensionRegistry));
              break;
            }
            case 66: {
              if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
                moduleExpression_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>();
                mutable_bitField0_ |= 0x00000080;
              }
              moduleExpression_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry));
              break;
            }
            case 74: {
              if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
                inlineModule_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule>();
                mutable_bitField0_ |= 0x00000100;
              }
              inlineModule_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          importedModule_ = java.util.Collections.unmodifiableList(importedModule_);
        }
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          importEntry_ = java.util.Collections.unmodifiableList(importEntry_);
        }
        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
          nameBinding_ = java.util.Collections.unmodifiableList(nameBinding_);
        }
        if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
          classModel_ = java.util.Collections.unmodifiableList(classModel_);
        }
        if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
          moduleExpression_ = java.util.Collections.unmodifiableList(moduleExpression_);
        }
        if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) {
          inlineModule_ = java.util.Collections.unmodifiableList(inlineModule_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Fragment> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Fragment>() {
      public Fragment parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Fragment(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Fragment> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int IMPORTED_MODULE_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule> importedModule_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule> getImportedModuleList() {
      return importedModule_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder> 
        getImportedModuleOrBuilderList() {
      return importedModule_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    public int getImportedModuleCount() {
      return importedModule_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule getImportedModule(int index) {
      return importedModule_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder getImportedModuleOrBuilder(
        int index) {
      return importedModule_.get(index);
    }

    public static final int IMPORT_ENTRY_FIELD_NUMBER = 2;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import> importEntry_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import> getImportEntryList() {
      return importEntry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder> 
        getImportEntryOrBuilderList() {
      return importEntry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    public int getImportEntryCount() {
      return importEntry_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import getImportEntry(int index) {
      return importEntry_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder getImportEntryOrBuilder(
        int index) {
      return importEntry_.get(index);
    }

    public static final int DECLARATION_BLOCK_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock declarationBlock_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
     */
    public boolean hasDeclarationBlock() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getDeclarationBlock() {
      return declarationBlock_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getDeclarationBlockOrBuilder() {
      return declarationBlock_;
    }

    public static final int EXPORT_BLOCK_FIELD_NUMBER = 4;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock exportBlock_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
     */
    public boolean hasExportBlock() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getExportBlock() {
      return exportBlock_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getExportBlockOrBuilder() {
      return exportBlock_;
    }

    public static final int INITIALIZER_BLOCK_FIELD_NUMBER = 5;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock initializerBlock_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
     */
    public boolean hasInitializerBlock() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getInitializerBlock() {
      return initializerBlock_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getInitializerBlockOrBuilder() {
      return initializerBlock_;
    }

    public static final int NAME_BINDING_FIELD_NUMBER = 6;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding> nameBinding_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding> getNameBindingList() {
      return nameBinding_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder> 
        getNameBindingOrBuilderList() {
      return nameBinding_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    public int getNameBindingCount() {
      return nameBinding_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding getNameBinding(int index) {
      return nameBinding_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder getNameBindingOrBuilder(
        int index) {
      return nameBinding_.get(index);
    }

    public static final int CLASS_MODEL_FIELD_NUMBER = 7;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel> classModel_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel> getClassModelList() {
      return classModel_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder> 
        getClassModelOrBuilderList() {
      return classModel_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    public int getClassModelCount() {
      return classModel_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel getClassModel(int index) {
      return classModel_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder getClassModelOrBuilder(
        int index) {
      return classModel_.get(index);
    }

    public static final int MODULE_EXPRESSION_FIELD_NUMBER = 8;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> moduleExpression_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getModuleExpressionList() {
      return moduleExpression_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
        getModuleExpressionOrBuilderList() {
      return moduleExpression_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    public int getModuleExpressionCount() {
      return moduleExpression_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getModuleExpression(int index) {
      return moduleExpression_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getModuleExpressionOrBuilder(
        int index) {
      return moduleExpression_.get(index);
    }

    public static final int INLINE_MODULE_FIELD_NUMBER = 9;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule> inlineModule_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule> getInlineModuleList() {
      return inlineModule_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder> 
        getInlineModuleOrBuilderList() {
      return inlineModule_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    public int getInlineModuleCount() {
      return inlineModule_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule getInlineModule(int index) {
      return inlineModule_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder getInlineModuleOrBuilder(
        int index) {
      return inlineModule_.get(index);
    }

    private void initFields() {
      importedModule_ = java.util.Collections.emptyList();
      importEntry_ = java.util.Collections.emptyList();
      declarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      exportBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      initializerBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      nameBinding_ = java.util.Collections.emptyList();
      classModel_ = java.util.Collections.emptyList();
      moduleExpression_ = java.util.Collections.emptyList();
      inlineModule_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getImportedModuleCount(); i++) {
        if (!getImportedModule(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getImportEntryCount(); i++) {
        if (!getImportEntry(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasDeclarationBlock()) {
        if (!getDeclarationBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasExportBlock()) {
        if (!getExportBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      if (hasInitializerBlock()) {
        if (!getInitializerBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getNameBindingCount(); i++) {
        if (!getNameBinding(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getClassModelCount(); i++) {
        if (!getClassModel(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getModuleExpressionCount(); i++) {
        if (!getModuleExpression(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getInlineModuleCount(); i++) {
        if (!getInlineModule(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < importedModule_.size(); i++) {
        output.writeMessage(1, importedModule_.get(i));
      }
      for (int i = 0; i < importEntry_.size(); i++) {
        output.writeMessage(2, importEntry_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(3, declarationBlock_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(4, exportBlock_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(5, initializerBlock_);
      }
      for (int i = 0; i < nameBinding_.size(); i++) {
        output.writeMessage(6, nameBinding_.get(i));
      }
      for (int i = 0; i < classModel_.size(); i++) {
        output.writeMessage(7, classModel_.get(i));
      }
      for (int i = 0; i < moduleExpression_.size(); i++) {
        output.writeMessage(8, moduleExpression_.get(i));
      }
      for (int i = 0; i < inlineModule_.size(); i++) {
        output.writeMessage(9, inlineModule_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < importedModule_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, importedModule_.get(i));
      }
      for (int i = 0; i < importEntry_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, importEntry_.get(i));
      }
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, declarationBlock_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(4, exportBlock_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(5, initializerBlock_);
      }
      for (int i = 0; i < nameBinding_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(6, nameBinding_.get(i));
      }
      for (int i = 0; i < classModel_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(7, classModel_.get(i));
      }
      for (int i = 0; i < moduleExpression_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(8, moduleExpression_.get(i));
      }
      for (int i = 0; i < inlineModule_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(9, inlineModule_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Fragment}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Fragment)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getImportedModuleFieldBuilder();
          getImportEntryFieldBuilder();
          getDeclarationBlockFieldBuilder();
          getExportBlockFieldBuilder();
          getInitializerBlockFieldBuilder();
          getNameBindingFieldBuilder();
          getClassModelFieldBuilder();
          getModuleExpressionFieldBuilder();
          getInlineModuleFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (importedModuleBuilder_ == null) {
          importedModule_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          importedModuleBuilder_.clear();
        }
        if (importEntryBuilder_ == null) {
          importEntry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          importEntryBuilder_.clear();
        }
        if (declarationBlockBuilder_ == null) {
          declarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        } else {
          declarationBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        if (exportBlockBuilder_ == null) {
          exportBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        } else {
          exportBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        if (initializerBlockBuilder_ == null) {
          initializerBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        } else {
          initializerBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        if (nameBindingBuilder_ == null) {
          nameBinding_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000020);
        } else {
          nameBindingBuilder_.clear();
        }
        if (classModelBuilder_ == null) {
          classModel_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000040);
        } else {
          classModelBuilder_.clear();
        }
        if (moduleExpressionBuilder_ == null) {
          moduleExpression_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000080);
        } else {
          moduleExpressionBuilder_.clear();
        }
        if (inlineModuleBuilder_ == null) {
          inlineModule_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000100);
        } else {
          inlineModuleBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (importedModuleBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            importedModule_ = java.util.Collections.unmodifiableList(importedModule_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.importedModule_ = importedModule_;
        } else {
          result.importedModule_ = importedModuleBuilder_.build();
        }
        if (importEntryBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            importEntry_ = java.util.Collections.unmodifiableList(importEntry_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.importEntry_ = importEntry_;
        } else {
          result.importEntry_ = importEntryBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000001;
        }
        if (declarationBlockBuilder_ == null) {
          result.declarationBlock_ = declarationBlock_;
        } else {
          result.declarationBlock_ = declarationBlockBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000002;
        }
        if (exportBlockBuilder_ == null) {
          result.exportBlock_ = exportBlock_;
        } else {
          result.exportBlock_ = exportBlockBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000004;
        }
        if (initializerBlockBuilder_ == null) {
          result.initializerBlock_ = initializerBlock_;
        } else {
          result.initializerBlock_ = initializerBlockBuilder_.build();
        }
        if (nameBindingBuilder_ == null) {
          if (((bitField0_ & 0x00000020) == 0x00000020)) {
            nameBinding_ = java.util.Collections.unmodifiableList(nameBinding_);
            bitField0_ = (bitField0_ & ~0x00000020);
          }
          result.nameBinding_ = nameBinding_;
        } else {
          result.nameBinding_ = nameBindingBuilder_.build();
        }
        if (classModelBuilder_ == null) {
          if (((bitField0_ & 0x00000040) == 0x00000040)) {
            classModel_ = java.util.Collections.unmodifiableList(classModel_);
            bitField0_ = (bitField0_ & ~0x00000040);
          }
          result.classModel_ = classModel_;
        } else {
          result.classModel_ = classModelBuilder_.build();
        }
        if (moduleExpressionBuilder_ == null) {
          if (((bitField0_ & 0x00000080) == 0x00000080)) {
            moduleExpression_ = java.util.Collections.unmodifiableList(moduleExpression_);
            bitField0_ = (bitField0_ & ~0x00000080);
          }
          result.moduleExpression_ = moduleExpression_;
        } else {
          result.moduleExpression_ = moduleExpressionBuilder_.build();
        }
        if (inlineModuleBuilder_ == null) {
          if (((bitField0_ & 0x00000100) == 0x00000100)) {
            inlineModule_ = java.util.Collections.unmodifiableList(inlineModule_);
            bitField0_ = (bitField0_ & ~0x00000100);
          }
          result.inlineModule_ = inlineModule_;
        } else {
          result.inlineModule_ = inlineModuleBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance()) return this;
        if (importedModuleBuilder_ == null) {
          if (!other.importedModule_.isEmpty()) {
            if (importedModule_.isEmpty()) {
              importedModule_ = other.importedModule_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureImportedModuleIsMutable();
              importedModule_.addAll(other.importedModule_);
            }
            onChanged();
          }
        } else {
          if (!other.importedModule_.isEmpty()) {
            if (importedModuleBuilder_.isEmpty()) {
              importedModuleBuilder_.dispose();
              importedModuleBuilder_ = null;
              importedModule_ = other.importedModule_;
              bitField0_ = (bitField0_ & ~0x00000001);
              importedModuleBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getImportedModuleFieldBuilder() : null;
            } else {
              importedModuleBuilder_.addAllMessages(other.importedModule_);
            }
          }
        }
        if (importEntryBuilder_ == null) {
          if (!other.importEntry_.isEmpty()) {
            if (importEntry_.isEmpty()) {
              importEntry_ = other.importEntry_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureImportEntryIsMutable();
              importEntry_.addAll(other.importEntry_);
            }
            onChanged();
          }
        } else {
          if (!other.importEntry_.isEmpty()) {
            if (importEntryBuilder_.isEmpty()) {
              importEntryBuilder_.dispose();
              importEntryBuilder_ = null;
              importEntry_ = other.importEntry_;
              bitField0_ = (bitField0_ & ~0x00000002);
              importEntryBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getImportEntryFieldBuilder() : null;
            } else {
              importEntryBuilder_.addAllMessages(other.importEntry_);
            }
          }
        }
        if (other.hasDeclarationBlock()) {
          mergeDeclarationBlock(other.getDeclarationBlock());
        }
        if (other.hasExportBlock()) {
          mergeExportBlock(other.getExportBlock());
        }
        if (other.hasInitializerBlock()) {
          mergeInitializerBlock(other.getInitializerBlock());
        }
        if (nameBindingBuilder_ == null) {
          if (!other.nameBinding_.isEmpty()) {
            if (nameBinding_.isEmpty()) {
              nameBinding_ = other.nameBinding_;
              bitField0_ = (bitField0_ & ~0x00000020);
            } else {
              ensureNameBindingIsMutable();
              nameBinding_.addAll(other.nameBinding_);
            }
            onChanged();
          }
        } else {
          if (!other.nameBinding_.isEmpty()) {
            if (nameBindingBuilder_.isEmpty()) {
              nameBindingBuilder_.dispose();
              nameBindingBuilder_ = null;
              nameBinding_ = other.nameBinding_;
              bitField0_ = (bitField0_ & ~0x00000020);
              nameBindingBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getNameBindingFieldBuilder() : null;
            } else {
              nameBindingBuilder_.addAllMessages(other.nameBinding_);
            }
          }
        }
        if (classModelBuilder_ == null) {
          if (!other.classModel_.isEmpty()) {
            if (classModel_.isEmpty()) {
              classModel_ = other.classModel_;
              bitField0_ = (bitField0_ & ~0x00000040);
            } else {
              ensureClassModelIsMutable();
              classModel_.addAll(other.classModel_);
            }
            onChanged();
          }
        } else {
          if (!other.classModel_.isEmpty()) {
            if (classModelBuilder_.isEmpty()) {
              classModelBuilder_.dispose();
              classModelBuilder_ = null;
              classModel_ = other.classModel_;
              bitField0_ = (bitField0_ & ~0x00000040);
              classModelBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getClassModelFieldBuilder() : null;
            } else {
              classModelBuilder_.addAllMessages(other.classModel_);
            }
          }
        }
        if (moduleExpressionBuilder_ == null) {
          if (!other.moduleExpression_.isEmpty()) {
            if (moduleExpression_.isEmpty()) {
              moduleExpression_ = other.moduleExpression_;
              bitField0_ = (bitField0_ & ~0x00000080);
            } else {
              ensureModuleExpressionIsMutable();
              moduleExpression_.addAll(other.moduleExpression_);
            }
            onChanged();
          }
        } else {
          if (!other.moduleExpression_.isEmpty()) {
            if (moduleExpressionBuilder_.isEmpty()) {
              moduleExpressionBuilder_.dispose();
              moduleExpressionBuilder_ = null;
              moduleExpression_ = other.moduleExpression_;
              bitField0_ = (bitField0_ & ~0x00000080);
              moduleExpressionBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getModuleExpressionFieldBuilder() : null;
            } else {
              moduleExpressionBuilder_.addAllMessages(other.moduleExpression_);
            }
          }
        }
        if (inlineModuleBuilder_ == null) {
          if (!other.inlineModule_.isEmpty()) {
            if (inlineModule_.isEmpty()) {
              inlineModule_ = other.inlineModule_;
              bitField0_ = (bitField0_ & ~0x00000100);
            } else {
              ensureInlineModuleIsMutable();
              inlineModule_.addAll(other.inlineModule_);
            }
            onChanged();
          }
        } else {
          if (!other.inlineModule_.isEmpty()) {
            if (inlineModuleBuilder_.isEmpty()) {
              inlineModuleBuilder_.dispose();
              inlineModuleBuilder_ = null;
              inlineModule_ = other.inlineModule_;
              bitField0_ = (bitField0_ & ~0x00000100);
              inlineModuleBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getInlineModuleFieldBuilder() : null;
            } else {
              inlineModuleBuilder_.addAllMessages(other.inlineModule_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getImportedModuleCount(); i++) {
          if (!getImportedModule(i).isInitialized()) {
            
            return false;
          }
        }
        for (int i = 0; i < getImportEntryCount(); i++) {
          if (!getImportEntry(i).isInitialized()) {
            
            return false;
          }
        }
        if (hasDeclarationBlock()) {
          if (!getDeclarationBlock().isInitialized()) {
            
            return false;
          }
        }
        if (hasExportBlock()) {
          if (!getExportBlock().isInitialized()) {
            
            return false;
          }
        }
        if (hasInitializerBlock()) {
          if (!getInitializerBlock().isInitialized()) {
            
            return false;
          }
        }
        for (int i = 0; i < getNameBindingCount(); i++) {
          if (!getNameBinding(i).isInitialized()) {
            
            return false;
          }
        }
        for (int i = 0; i < getClassModelCount(); i++) {
          if (!getClassModel(i).isInitialized()) {
            
            return false;
          }
        }
        for (int i = 0; i < getModuleExpressionCount(); i++) {
          if (!getModuleExpression(i).isInitialized()) {
            
            return false;
          }
        }
        for (int i = 0; i < getInlineModuleCount(); i++) {
          if (!getInlineModule(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule> importedModule_ =
        java.util.Collections.emptyList();
      private void ensureImportedModuleIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          importedModule_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule>(importedModule_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder> importedModuleBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule> getImportedModuleList() {
        if (importedModuleBuilder_ == null) {
          return java.util.Collections.unmodifiableList(importedModule_);
        } else {
          return importedModuleBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public int getImportedModuleCount() {
        if (importedModuleBuilder_ == null) {
          return importedModule_.size();
        } else {
          return importedModuleBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule getImportedModule(int index) {
        if (importedModuleBuilder_ == null) {
          return importedModule_.get(index);
        } else {
          return importedModuleBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder setImportedModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule value) {
        if (importedModuleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImportedModuleIsMutable();
          importedModule_.set(index, value);
          onChanged();
        } else {
          importedModuleBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder setImportedModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder builderForValue) {
        if (importedModuleBuilder_ == null) {
          ensureImportedModuleIsMutable();
          importedModule_.set(index, builderForValue.build());
          onChanged();
        } else {
          importedModuleBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder addImportedModule(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule value) {
        if (importedModuleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImportedModuleIsMutable();
          importedModule_.add(value);
          onChanged();
        } else {
          importedModuleBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder addImportedModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule value) {
        if (importedModuleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImportedModuleIsMutable();
          importedModule_.add(index, value);
          onChanged();
        } else {
          importedModuleBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder addImportedModule(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder builderForValue) {
        if (importedModuleBuilder_ == null) {
          ensureImportedModuleIsMutable();
          importedModule_.add(builderForValue.build());
          onChanged();
        } else {
          importedModuleBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder addImportedModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder builderForValue) {
        if (importedModuleBuilder_ == null) {
          ensureImportedModuleIsMutable();
          importedModule_.add(index, builderForValue.build());
          onChanged();
        } else {
          importedModuleBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder addAllImportedModule(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule> values) {
        if (importedModuleBuilder_ == null) {
          ensureImportedModuleIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, importedModule_);
          onChanged();
        } else {
          importedModuleBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder clearImportedModule() {
        if (importedModuleBuilder_ == null) {
          importedModule_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          importedModuleBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public Builder removeImportedModule(int index) {
        if (importedModuleBuilder_ == null) {
          ensureImportedModuleIsMutable();
          importedModule_.remove(index);
          onChanged();
        } else {
          importedModuleBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder getImportedModuleBuilder(
          int index) {
        return getImportedModuleFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder getImportedModuleOrBuilder(
          int index) {
        if (importedModuleBuilder_ == null) {
          return importedModule_.get(index);  } else {
          return importedModuleBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder> 
           getImportedModuleOrBuilderList() {
        if (importedModuleBuilder_ != null) {
          return importedModuleBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(importedModule_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder addImportedModuleBuilder() {
        return getImportedModuleFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder addImportedModuleBuilder(
          int index) {
        return getImportedModuleFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ImportedModule imported_module = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder> 
           getImportedModuleBuilderList() {
        return getImportedModuleFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder> 
          getImportedModuleFieldBuilder() {
        if (importedModuleBuilder_ == null) {
          importedModuleBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder>(
                  importedModule_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          importedModule_ = null;
        }
        return importedModuleBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import> importEntry_ =
        java.util.Collections.emptyList();
      private void ensureImportEntryIsMutable() {
        if (!((bitField0_ & 0x00000002) == 0x00000002)) {
          importEntry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import>(importEntry_);
          bitField0_ |= 0x00000002;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder> importEntryBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import> getImportEntryList() {
        if (importEntryBuilder_ == null) {
          return java.util.Collections.unmodifiableList(importEntry_);
        } else {
          return importEntryBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public int getImportEntryCount() {
        if (importEntryBuilder_ == null) {
          return importEntry_.size();
        } else {
          return importEntryBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import getImportEntry(int index) {
        if (importEntryBuilder_ == null) {
          return importEntry_.get(index);
        } else {
          return importEntryBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder setImportEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import value) {
        if (importEntryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImportEntryIsMutable();
          importEntry_.set(index, value);
          onChanged();
        } else {
          importEntryBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder setImportEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder builderForValue) {
        if (importEntryBuilder_ == null) {
          ensureImportEntryIsMutable();
          importEntry_.set(index, builderForValue.build());
          onChanged();
        } else {
          importEntryBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder addImportEntry(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import value) {
        if (importEntryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImportEntryIsMutable();
          importEntry_.add(value);
          onChanged();
        } else {
          importEntryBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder addImportEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import value) {
        if (importEntryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureImportEntryIsMutable();
          importEntry_.add(index, value);
          onChanged();
        } else {
          importEntryBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder addImportEntry(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder builderForValue) {
        if (importEntryBuilder_ == null) {
          ensureImportEntryIsMutable();
          importEntry_.add(builderForValue.build());
          onChanged();
        } else {
          importEntryBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder addImportEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder builderForValue) {
        if (importEntryBuilder_ == null) {
          ensureImportEntryIsMutable();
          importEntry_.add(index, builderForValue.build());
          onChanged();
        } else {
          importEntryBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder addAllImportEntry(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import> values) {
        if (importEntryBuilder_ == null) {
          ensureImportEntryIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, importEntry_);
          onChanged();
        } else {
          importEntryBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder clearImportEntry() {
        if (importEntryBuilder_ == null) {
          importEntry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          importEntryBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public Builder removeImportEntry(int index) {
        if (importEntryBuilder_ == null) {
          ensureImportEntryIsMutable();
          importEntry_.remove(index);
          onChanged();
        } else {
          importEntryBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder getImportEntryBuilder(
          int index) {
        return getImportEntryFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder getImportEntryOrBuilder(
          int index) {
        if (importEntryBuilder_ == null) {
          return importEntry_.get(index);  } else {
          return importEntryBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder> 
           getImportEntryOrBuilderList() {
        if (importEntryBuilder_ != null) {
          return importEntryBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(importEntry_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder addImportEntryBuilder() {
        return getImportEntryFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder addImportEntryBuilder(
          int index) {
        return getImportEntryFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Import import_entry = 2;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder> 
           getImportEntryBuilderList() {
        return getImportEntryFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder> 
          getImportEntryFieldBuilder() {
        if (importEntryBuilder_ == null) {
          importEntryBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder>(
                  importEntry_,
                  ((bitField0_ & 0x00000002) == 0x00000002),
                  getParentForChildren(),
                  isClean());
          importEntry_ = null;
        }
        return importEntryBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock declarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> declarationBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public boolean hasDeclarationBlock() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getDeclarationBlock() {
        if (declarationBlockBuilder_ == null) {
          return declarationBlock_;
        } else {
          return declarationBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public Builder setDeclarationBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (declarationBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          declarationBlock_ = value;
          onChanged();
        } else {
          declarationBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public Builder setDeclarationBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder builderForValue) {
        if (declarationBlockBuilder_ == null) {
          declarationBlock_ = builderForValue.build();
          onChanged();
        } else {
          declarationBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public Builder mergeDeclarationBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (declarationBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              declarationBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) {
            declarationBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder(declarationBlock_).mergeFrom(value).buildPartial();
          } else {
            declarationBlock_ = value;
          }
          onChanged();
        } else {
          declarationBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public Builder clearDeclarationBlock() {
        if (declarationBlockBuilder_ == null) {
          declarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
          onChanged();
        } else {
          declarationBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder getDeclarationBlockBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getDeclarationBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getDeclarationBlockOrBuilder() {
        if (declarationBlockBuilder_ != null) {
          return declarationBlockBuilder_.getMessageOrBuilder();
        } else {
          return declarationBlock_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock declaration_block = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> 
          getDeclarationBlockFieldBuilder() {
        if (declarationBlockBuilder_ == null) {
          declarationBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder>(
                  getDeclarationBlock(),
                  getParentForChildren(),
                  isClean());
          declarationBlock_ = null;
        }
        return declarationBlockBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock exportBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> exportBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public boolean hasExportBlock() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getExportBlock() {
        if (exportBlockBuilder_ == null) {
          return exportBlock_;
        } else {
          return exportBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public Builder setExportBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (exportBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          exportBlock_ = value;
          onChanged();
        } else {
          exportBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public Builder setExportBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder builderForValue) {
        if (exportBlockBuilder_ == null) {
          exportBlock_ = builderForValue.build();
          onChanged();
        } else {
          exportBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public Builder mergeExportBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (exportBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              exportBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) {
            exportBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder(exportBlock_).mergeFrom(value).buildPartial();
          } else {
            exportBlock_ = value;
          }
          onChanged();
        } else {
          exportBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public Builder clearExportBlock() {
        if (exportBlockBuilder_ == null) {
          exportBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
          onChanged();
        } else {
          exportBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder getExportBlockBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getExportBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getExportBlockOrBuilder() {
        if (exportBlockBuilder_ != null) {
          return exportBlockBuilder_.getMessageOrBuilder();
        } else {
          return exportBlock_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock export_block = 4;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> 
          getExportBlockFieldBuilder() {
        if (exportBlockBuilder_ == null) {
          exportBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder>(
                  getExportBlock(),
                  getParentForChildren(),
                  isClean());
          exportBlock_ = null;
        }
        return exportBlockBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock initializerBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> initializerBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public boolean hasInitializerBlock() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getInitializerBlock() {
        if (initializerBlockBuilder_ == null) {
          return initializerBlock_;
        } else {
          return initializerBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public Builder setInitializerBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (initializerBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          initializerBlock_ = value;
          onChanged();
        } else {
          initializerBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public Builder setInitializerBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder builderForValue) {
        if (initializerBlockBuilder_ == null) {
          initializerBlock_ = builderForValue.build();
          onChanged();
        } else {
          initializerBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public Builder mergeInitializerBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (initializerBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000010) == 0x00000010) &&
              initializerBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) {
            initializerBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder(initializerBlock_).mergeFrom(value).buildPartial();
          } else {
            initializerBlock_ = value;
          }
          onChanged();
        } else {
          initializerBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public Builder clearInitializerBlock() {
        if (initializerBlockBuilder_ == null) {
          initializerBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
          onChanged();
        } else {
          initializerBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder getInitializerBlockBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getInitializerBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getInitializerBlockOrBuilder() {
        if (initializerBlockBuilder_ != null) {
          return initializerBlockBuilder_.getMessageOrBuilder();
        } else {
          return initializerBlock_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock initializer_block = 5;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> 
          getInitializerBlockFieldBuilder() {
        if (initializerBlockBuilder_ == null) {
          initializerBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder>(
                  getInitializerBlock(),
                  getParentForChildren(),
                  isClean());
          initializerBlock_ = null;
        }
        return initializerBlockBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding> nameBinding_ =
        java.util.Collections.emptyList();
      private void ensureNameBindingIsMutable() {
        if (!((bitField0_ & 0x00000020) == 0x00000020)) {
          nameBinding_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding>(nameBinding_);
          bitField0_ |= 0x00000020;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder> nameBindingBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding> getNameBindingList() {
        if (nameBindingBuilder_ == null) {
          return java.util.Collections.unmodifiableList(nameBinding_);
        } else {
          return nameBindingBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public int getNameBindingCount() {
        if (nameBindingBuilder_ == null) {
          return nameBinding_.size();
        } else {
          return nameBindingBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding getNameBinding(int index) {
        if (nameBindingBuilder_ == null) {
          return nameBinding_.get(index);
        } else {
          return nameBindingBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder setNameBinding(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding value) {
        if (nameBindingBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureNameBindingIsMutable();
          nameBinding_.set(index, value);
          onChanged();
        } else {
          nameBindingBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder setNameBinding(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder builderForValue) {
        if (nameBindingBuilder_ == null) {
          ensureNameBindingIsMutable();
          nameBinding_.set(index, builderForValue.build());
          onChanged();
        } else {
          nameBindingBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder addNameBinding(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding value) {
        if (nameBindingBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureNameBindingIsMutable();
          nameBinding_.add(value);
          onChanged();
        } else {
          nameBindingBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder addNameBinding(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding value) {
        if (nameBindingBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureNameBindingIsMutable();
          nameBinding_.add(index, value);
          onChanged();
        } else {
          nameBindingBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder addNameBinding(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder builderForValue) {
        if (nameBindingBuilder_ == null) {
          ensureNameBindingIsMutable();
          nameBinding_.add(builderForValue.build());
          onChanged();
        } else {
          nameBindingBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder addNameBinding(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder builderForValue) {
        if (nameBindingBuilder_ == null) {
          ensureNameBindingIsMutable();
          nameBinding_.add(index, builderForValue.build());
          onChanged();
        } else {
          nameBindingBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder addAllNameBinding(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding> values) {
        if (nameBindingBuilder_ == null) {
          ensureNameBindingIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, nameBinding_);
          onChanged();
        } else {
          nameBindingBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder clearNameBinding() {
        if (nameBindingBuilder_ == null) {
          nameBinding_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000020);
          onChanged();
        } else {
          nameBindingBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public Builder removeNameBinding(int index) {
        if (nameBindingBuilder_ == null) {
          ensureNameBindingIsMutable();
          nameBinding_.remove(index);
          onChanged();
        } else {
          nameBindingBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder getNameBindingBuilder(
          int index) {
        return getNameBindingFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder getNameBindingOrBuilder(
          int index) {
        if (nameBindingBuilder_ == null) {
          return nameBinding_.get(index);  } else {
          return nameBindingBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder> 
           getNameBindingOrBuilderList() {
        if (nameBindingBuilder_ != null) {
          return nameBindingBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(nameBinding_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder addNameBindingBuilder() {
        return getNameBindingFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder addNameBindingBuilder(
          int index) {
        return getNameBindingFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.NameBinding name_binding = 6;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder> 
           getNameBindingBuilderList() {
        return getNameBindingFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder> 
          getNameBindingFieldBuilder() {
        if (nameBindingBuilder_ == null) {
          nameBindingBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder>(
                  nameBinding_,
                  ((bitField0_ & 0x00000020) == 0x00000020),
                  getParentForChildren(),
                  isClean());
          nameBinding_ = null;
        }
        return nameBindingBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel> classModel_ =
        java.util.Collections.emptyList();
      private void ensureClassModelIsMutable() {
        if (!((bitField0_ & 0x00000040) == 0x00000040)) {
          classModel_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel>(classModel_);
          bitField0_ |= 0x00000040;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder> classModelBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel> getClassModelList() {
        if (classModelBuilder_ == null) {
          return java.util.Collections.unmodifiableList(classModel_);
        } else {
          return classModelBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public int getClassModelCount() {
        if (classModelBuilder_ == null) {
          return classModel_.size();
        } else {
          return classModelBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel getClassModel(int index) {
        if (classModelBuilder_ == null) {
          return classModel_.get(index);
        } else {
          return classModelBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder setClassModel(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel value) {
        if (classModelBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureClassModelIsMutable();
          classModel_.set(index, value);
          onChanged();
        } else {
          classModelBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder setClassModel(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder builderForValue) {
        if (classModelBuilder_ == null) {
          ensureClassModelIsMutable();
          classModel_.set(index, builderForValue.build());
          onChanged();
        } else {
          classModelBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder addClassModel(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel value) {
        if (classModelBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureClassModelIsMutable();
          classModel_.add(value);
          onChanged();
        } else {
          classModelBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder addClassModel(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel value) {
        if (classModelBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureClassModelIsMutable();
          classModel_.add(index, value);
          onChanged();
        } else {
          classModelBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder addClassModel(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder builderForValue) {
        if (classModelBuilder_ == null) {
          ensureClassModelIsMutable();
          classModel_.add(builderForValue.build());
          onChanged();
        } else {
          classModelBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder addClassModel(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder builderForValue) {
        if (classModelBuilder_ == null) {
          ensureClassModelIsMutable();
          classModel_.add(index, builderForValue.build());
          onChanged();
        } else {
          classModelBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder addAllClassModel(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel> values) {
        if (classModelBuilder_ == null) {
          ensureClassModelIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, classModel_);
          onChanged();
        } else {
          classModelBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder clearClassModel() {
        if (classModelBuilder_ == null) {
          classModel_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000040);
          onChanged();
        } else {
          classModelBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public Builder removeClassModel(int index) {
        if (classModelBuilder_ == null) {
          ensureClassModelIsMutable();
          classModel_.remove(index);
          onChanged();
        } else {
          classModelBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder getClassModelBuilder(
          int index) {
        return getClassModelFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder getClassModelOrBuilder(
          int index) {
        if (classModelBuilder_ == null) {
          return classModel_.get(index);  } else {
          return classModelBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder> 
           getClassModelOrBuilderList() {
        if (classModelBuilder_ != null) {
          return classModelBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(classModel_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder addClassModelBuilder() {
        return getClassModelFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder addClassModelBuilder(
          int index) {
        return getClassModelFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.ClassModel class_model = 7;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder> 
           getClassModelBuilderList() {
        return getClassModelFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder> 
          getClassModelFieldBuilder() {
        if (classModelBuilder_ == null) {
          classModelBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder>(
                  classModel_,
                  ((bitField0_ & 0x00000040) == 0x00000040),
                  getParentForChildren(),
                  isClean());
          classModel_ = null;
        }
        return classModelBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> moduleExpression_ =
        java.util.Collections.emptyList();
      private void ensureModuleExpressionIsMutable() {
        if (!((bitField0_ & 0x00000080) == 0x00000080)) {
          moduleExpression_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression>(moduleExpression_);
          bitField0_ |= 0x00000080;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> moduleExpressionBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> getModuleExpressionList() {
        if (moduleExpressionBuilder_ == null) {
          return java.util.Collections.unmodifiableList(moduleExpression_);
        } else {
          return moduleExpressionBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public int getModuleExpressionCount() {
        if (moduleExpressionBuilder_ == null) {
          return moduleExpression_.size();
        } else {
          return moduleExpressionBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getModuleExpression(int index) {
        if (moduleExpressionBuilder_ == null) {
          return moduleExpression_.get(index);
        } else {
          return moduleExpressionBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder setModuleExpression(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (moduleExpressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureModuleExpressionIsMutable();
          moduleExpression_.set(index, value);
          onChanged();
        } else {
          moduleExpressionBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder setModuleExpression(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (moduleExpressionBuilder_ == null) {
          ensureModuleExpressionIsMutable();
          moduleExpression_.set(index, builderForValue.build());
          onChanged();
        } else {
          moduleExpressionBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder addModuleExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (moduleExpressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureModuleExpressionIsMutable();
          moduleExpression_.add(value);
          onChanged();
        } else {
          moduleExpressionBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder addModuleExpression(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (moduleExpressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureModuleExpressionIsMutable();
          moduleExpression_.add(index, value);
          onChanged();
        } else {
          moduleExpressionBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder addModuleExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (moduleExpressionBuilder_ == null) {
          ensureModuleExpressionIsMutable();
          moduleExpression_.add(builderForValue.build());
          onChanged();
        } else {
          moduleExpressionBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder addModuleExpression(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (moduleExpressionBuilder_ == null) {
          ensureModuleExpressionIsMutable();
          moduleExpression_.add(index, builderForValue.build());
          onChanged();
        } else {
          moduleExpressionBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder addAllModuleExpression(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression> values) {
        if (moduleExpressionBuilder_ == null) {
          ensureModuleExpressionIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, moduleExpression_);
          onChanged();
        } else {
          moduleExpressionBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder clearModuleExpression() {
        if (moduleExpressionBuilder_ == null) {
          moduleExpression_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000080);
          onChanged();
        } else {
          moduleExpressionBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public Builder removeModuleExpression(int index) {
        if (moduleExpressionBuilder_ == null) {
          ensureModuleExpressionIsMutable();
          moduleExpression_.remove(index);
          onChanged();
        } else {
          moduleExpressionBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getModuleExpressionBuilder(
          int index) {
        return getModuleExpressionFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getModuleExpressionOrBuilder(
          int index) {
        if (moduleExpressionBuilder_ == null) {
          return moduleExpression_.get(index);  } else {
          return moduleExpressionBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
           getModuleExpressionOrBuilderList() {
        if (moduleExpressionBuilder_ != null) {
          return moduleExpressionBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(moduleExpression_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addModuleExpressionBuilder() {
        return getModuleExpressionFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder addModuleExpressionBuilder(
          int index) {
        return getModuleExpressionFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Expression module_expression = 8;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder> 
           getModuleExpressionBuilderList() {
        return getModuleExpressionFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getModuleExpressionFieldBuilder() {
        if (moduleExpressionBuilder_ == null) {
          moduleExpressionBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  moduleExpression_,
                  ((bitField0_ & 0x00000080) == 0x00000080),
                  getParentForChildren(),
                  isClean());
          moduleExpression_ = null;
        }
        return moduleExpressionBuilder_;
      }

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule> inlineModule_ =
        java.util.Collections.emptyList();
      private void ensureInlineModuleIsMutable() {
        if (!((bitField0_ & 0x00000100) == 0x00000100)) {
          inlineModule_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule>(inlineModule_);
          bitField0_ |= 0x00000100;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder> inlineModuleBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule> getInlineModuleList() {
        if (inlineModuleBuilder_ == null) {
          return java.util.Collections.unmodifiableList(inlineModule_);
        } else {
          return inlineModuleBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public int getInlineModuleCount() {
        if (inlineModuleBuilder_ == null) {
          return inlineModule_.size();
        } else {
          return inlineModuleBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule getInlineModule(int index) {
        if (inlineModuleBuilder_ == null) {
          return inlineModule_.get(index);
        } else {
          return inlineModuleBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder setInlineModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule value) {
        if (inlineModuleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureInlineModuleIsMutable();
          inlineModule_.set(index, value);
          onChanged();
        } else {
          inlineModuleBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder setInlineModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder builderForValue) {
        if (inlineModuleBuilder_ == null) {
          ensureInlineModuleIsMutable();
          inlineModule_.set(index, builderForValue.build());
          onChanged();
        } else {
          inlineModuleBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder addInlineModule(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule value) {
        if (inlineModuleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureInlineModuleIsMutable();
          inlineModule_.add(value);
          onChanged();
        } else {
          inlineModuleBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder addInlineModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule value) {
        if (inlineModuleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureInlineModuleIsMutable();
          inlineModule_.add(index, value);
          onChanged();
        } else {
          inlineModuleBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder addInlineModule(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder builderForValue) {
        if (inlineModuleBuilder_ == null) {
          ensureInlineModuleIsMutable();
          inlineModule_.add(builderForValue.build());
          onChanged();
        } else {
          inlineModuleBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder addInlineModule(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder builderForValue) {
        if (inlineModuleBuilder_ == null) {
          ensureInlineModuleIsMutable();
          inlineModule_.add(index, builderForValue.build());
          onChanged();
        } else {
          inlineModuleBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder addAllInlineModule(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule> values) {
        if (inlineModuleBuilder_ == null) {
          ensureInlineModuleIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, inlineModule_);
          onChanged();
        } else {
          inlineModuleBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder clearInlineModule() {
        if (inlineModuleBuilder_ == null) {
          inlineModule_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000100);
          onChanged();
        } else {
          inlineModuleBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public Builder removeInlineModule(int index) {
        if (inlineModuleBuilder_ == null) {
          ensureInlineModuleIsMutable();
          inlineModule_.remove(index);
          onChanged();
        } else {
          inlineModuleBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder getInlineModuleBuilder(
          int index) {
        return getInlineModuleFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder getInlineModuleOrBuilder(
          int index) {
        if (inlineModuleBuilder_ == null) {
          return inlineModule_.get(index);  } else {
          return inlineModuleBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder> 
           getInlineModuleOrBuilderList() {
        if (inlineModuleBuilder_ != null) {
          return inlineModuleBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(inlineModule_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder addInlineModuleBuilder() {
        return getInlineModuleFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder addInlineModuleBuilder(
          int index) {
        return getInlineModuleFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.InlineModule inline_module = 9;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder> 
           getInlineModuleBuilderList() {
        return getInlineModuleFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder> 
          getInlineModuleFieldBuilder() {
        if (inlineModuleBuilder_ == null) {
          inlineModuleBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder>(
                  inlineModule_,
                  ((bitField0_ & 0x00000100) == 0x00000100),
                  getParentForChildren(),
                  isClean());
          inlineModule_ = null;
        }
        return inlineModuleBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Fragment)
    }

    static {
      defaultInstance = new Fragment(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Fragment)
  }

  public interface ImportedModuleOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ImportedModule)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 external_name_id = 1;</code>
     */
    boolean hasExternalNameId();
    /**
     * <code>required int32 external_name_id = 1;</code>
     */
    int getExternalNameId();

    /**
     * <code>required int32 internal_name_id = 2;</code>
     */
    boolean hasInternalNameId();
    /**
     * <code>required int32 internal_name_id = 2;</code>
     */
    int getInternalNameId();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
     */
    boolean hasPlainReference();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getPlainReference();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getPlainReferenceOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ImportedModule}
   */
  public static final class ImportedModule extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ImportedModule)
      ImportedModuleOrBuilder {
    // Use ImportedModule.newBuilder() to construct.
    private ImportedModule(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ImportedModule(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ImportedModule defaultInstance;
    public static ImportedModule getDefaultInstance() {
      return defaultInstance;
    }

    public ImportedModule getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ImportedModule(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              externalNameId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              internalNameId_ = input.readInt32();
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = plainReference_.toBuilder();
              }
              plainReference_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(plainReference_);
                plainReference_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ImportedModule> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ImportedModule>() {
      public ImportedModule parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ImportedModule(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ImportedModule> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int EXTERNAL_NAME_ID_FIELD_NUMBER = 1;
    private int externalNameId_;
    /**
     * <code>required int32 external_name_id = 1;</code>
     */
    public boolean hasExternalNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 external_name_id = 1;</code>
     */
    public int getExternalNameId() {
      return externalNameId_;
    }

    public static final int INTERNAL_NAME_ID_FIELD_NUMBER = 2;
    private int internalNameId_;
    /**
     * <code>required int32 internal_name_id = 2;</code>
     */
    public boolean hasInternalNameId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 internal_name_id = 2;</code>
     */
    public int getInternalNameId() {
      return internalNameId_;
    }

    public static final int PLAIN_REFERENCE_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression plainReference_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
     */
    public boolean hasPlainReference() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getPlainReference() {
      return plainReference_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getPlainReferenceOrBuilder() {
      return plainReference_;
    }

    private void initFields() {
      externalNameId_ = 0;
      internalNameId_ = 0;
      plainReference_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasExternalNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasInternalNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasPlainReference()) {
        if (!getPlainReference().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, externalNameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, internalNameId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, plainReference_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, externalNameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, internalNameId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, plainReference_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ImportedModule}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ImportedModule)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModuleOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPlainReferenceFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        externalNameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        internalNameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        if (plainReferenceBuilder_ == null) {
          plainReference_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          plainReferenceBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.externalNameId_ = externalNameId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.internalNameId_ = internalNameId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (plainReferenceBuilder_ == null) {
          result.plainReference_ = plainReference_;
        } else {
          result.plainReference_ = plainReferenceBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule.getDefaultInstance()) return this;
        if (other.hasExternalNameId()) {
          setExternalNameId(other.getExternalNameId());
        }
        if (other.hasInternalNameId()) {
          setInternalNameId(other.getInternalNameId());
        }
        if (other.hasPlainReference()) {
          mergePlainReference(other.getPlainReference());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasExternalNameId()) {
          
          return false;
        }
        if (!hasInternalNameId()) {
          
          return false;
        }
        if (hasPlainReference()) {
          if (!getPlainReference().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportedModule) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int externalNameId_ ;
      /**
       * <code>required int32 external_name_id = 1;</code>
       */
      public boolean hasExternalNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 external_name_id = 1;</code>
       */
      public int getExternalNameId() {
        return externalNameId_;
      }
      /**
       * <code>required int32 external_name_id = 1;</code>
       */
      public Builder setExternalNameId(int value) {
        bitField0_ |= 0x00000001;
        externalNameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 external_name_id = 1;</code>
       */
      public Builder clearExternalNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        externalNameId_ = 0;
        onChanged();
        return this;
      }

      private int internalNameId_ ;
      /**
       * <code>required int32 internal_name_id = 2;</code>
       */
      public boolean hasInternalNameId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int32 internal_name_id = 2;</code>
       */
      public int getInternalNameId() {
        return internalNameId_;
      }
      /**
       * <code>required int32 internal_name_id = 2;</code>
       */
      public Builder setInternalNameId(int value) {
        bitField0_ |= 0x00000002;
        internalNameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 internal_name_id = 2;</code>
       */
      public Builder clearInternalNameId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        internalNameId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression plainReference_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> plainReferenceBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public boolean hasPlainReference() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getPlainReference() {
        if (plainReferenceBuilder_ == null) {
          return plainReference_;
        } else {
          return plainReferenceBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public Builder setPlainReference(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (plainReferenceBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          plainReference_ = value;
          onChanged();
        } else {
          plainReferenceBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public Builder setPlainReference(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (plainReferenceBuilder_ == null) {
          plainReference_ = builderForValue.build();
          onChanged();
        } else {
          plainReferenceBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public Builder mergePlainReference(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (plainReferenceBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              plainReference_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            plainReference_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(plainReference_).mergeFrom(value).buildPartial();
          } else {
            plainReference_ = value;
          }
          onChanged();
        } else {
          plainReferenceBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public Builder clearPlainReference() {
        if (plainReferenceBuilder_ == null) {
          plainReference_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          plainReferenceBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getPlainReferenceBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getPlainReferenceFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getPlainReferenceOrBuilder() {
        if (plainReferenceBuilder_ != null) {
          return plainReferenceBuilder_.getMessageOrBuilder();
        } else {
          return plainReference_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.Expression plain_reference = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getPlainReferenceFieldBuilder() {
        if (plainReferenceBuilder_ == null) {
          plainReferenceBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getPlainReference(),
                  getParentForChildren(),
                  isClean());
          plainReference_ = null;
        }
        return plainReferenceBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ImportedModule)
    }

    static {
      defaultInstance = new ImportedModule(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ImportedModule)
  }

  public interface ImportOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Import)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 signature_id = 1;</code>
     */
    boolean hasSignatureId();
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    int getSignatureId();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    boolean hasExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Import}
   */
  public static final class Import extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Import)
      ImportOrBuilder {
    // Use Import.newBuilder() to construct.
    private Import(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Import(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Import defaultInstance;
    public static Import getDefaultInstance() {
      return defaultInstance;
    }

    public Import getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Import(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              signatureId_ = input.readInt32();
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = expression_.toBuilder();
              }
              expression_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(expression_);
                expression_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Import> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Import>() {
      public Import parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Import(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Import> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int SIGNATURE_ID_FIELD_NUMBER = 1;
    private int signatureId_;
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    public boolean hasSignatureId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    public int getSignatureId() {
      return signatureId_;
    }

    public static final int EXPRESSION_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression expression_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public boolean hasExpression() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
      return expression_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
      return expression_;
    }

    private void initFields() {
      signatureId_ = 0;
      expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasSignatureId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasExpression()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getExpression().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, signatureId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, expression_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, signatureId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, expression_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Import}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Import)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ImportOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getExpressionFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        signatureId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (expressionBuilder_ == null) {
          expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
        } else {
          expressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.signatureId_ = signatureId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (expressionBuilder_ == null) {
          result.expression_ = expression_;
        } else {
          result.expression_ = expressionBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import.getDefaultInstance()) return this;
        if (other.hasSignatureId()) {
          setSignatureId(other.getSignatureId());
        }
        if (other.hasExpression()) {
          mergeExpression(other.getExpression());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasSignatureId()) {
          
          return false;
        }
        if (!hasExpression()) {
          
          return false;
        }
        if (!getExpression().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Import) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int signatureId_ ;
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public boolean hasSignatureId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public int getSignatureId() {
        return signatureId_;
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public Builder setSignatureId(int value) {
        bitField0_ |= 0x00000001;
        signatureId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public Builder clearSignatureId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        signatureId_ = 0;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> expressionBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public boolean hasExpression() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression getExpression() {
        if (expressionBuilder_ == null) {
          return expression_;
        } else {
          return expressionBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder setExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          expression_ = value;
          onChanged();
        } else {
          expressionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder setExpression(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder builderForValue) {
        if (expressionBuilder_ == null) {
          expression_ = builderForValue.build();
          onChanged();
        } else {
          expressionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder mergeExpression(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression value) {
        if (expressionBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              expression_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance()) {
            expression_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.newBuilder(expression_).mergeFrom(value).buildPartial();
          } else {
            expression_ = value;
          }
          onChanged();
        } else {
          expressionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public Builder clearExpression() {
        if (expressionBuilder_ == null) {
          expression_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.getDefaultInstance();
          onChanged();
        } else {
          expressionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder getExpressionBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getExpressionFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder getExpressionOrBuilder() {
        if (expressionBuilder_ != null) {
          return expressionBuilder_.getMessageOrBuilder();
        } else {
          return expression_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Expression expression = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder> 
          getExpressionFieldBuilder() {
        if (expressionBuilder_ == null) {
          expressionBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Expression.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ExpressionOrBuilder>(
                  getExpression(),
                  getParentForChildren(),
                  isClean());
          expression_ = null;
        }
        return expressionBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Import)
    }

    static {
      defaultInstance = new Import(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Import)
  }

  public interface NameBindingOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.NameBinding)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 signature_id = 1;</code>
     */
    boolean hasSignatureId();
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    int getSignatureId();

    /**
     * <code>required int32 nameId = 2;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 nameId = 2;</code>
     */
    int getNameId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NameBinding}
   */
  public static final class NameBinding extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.NameBinding)
      NameBindingOrBuilder {
    // Use NameBinding.newBuilder() to construct.
    private NameBinding(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private NameBinding(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final NameBinding defaultInstance;
    public static NameBinding getDefaultInstance() {
      return defaultInstance;
    }

    public NameBinding getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private NameBinding(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              signatureId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              nameId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<NameBinding> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<NameBinding>() {
      public NameBinding parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new NameBinding(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<NameBinding> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int SIGNATURE_ID_FIELD_NUMBER = 1;
    private int signatureId_;
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    public boolean hasSignatureId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    public int getSignatureId() {
      return signatureId_;
    }

    public static final int NAMEID_FIELD_NUMBER = 2;
    private int nameId_;
    /**
     * <code>required int32 nameId = 2;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 nameId = 2;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    private void initFields() {
      signatureId_ = 0;
      nameId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasSignatureId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, signatureId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, nameId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, signatureId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, nameId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NameBinding}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.NameBinding)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBindingOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        signatureId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.signatureId_ = signatureId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.nameId_ = nameId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding.getDefaultInstance()) return this;
        if (other.hasSignatureId()) {
          setSignatureId(other.getSignatureId());
        }
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasSignatureId()) {
          
          return false;
        }
        if (!hasNameId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameBinding) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int signatureId_ ;
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public boolean hasSignatureId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public int getSignatureId() {
        return signatureId_;
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public Builder setSignatureId(int value) {
        bitField0_ |= 0x00000001;
        signatureId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public Builder clearSignatureId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        signatureId_ = 0;
        onChanged();
        return this;
      }

      private int nameId_ ;
      /**
       * <code>required int32 nameId = 2;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int32 nameId = 2;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 nameId = 2;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000002;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 nameId = 2;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        nameId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.NameBinding)
    }

    static {
      defaultInstance = new NameBinding(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.NameBinding)
  }

  public interface ClassModelOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.ClassModel)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 name_id = 1;</code>
     */
    boolean hasNameId();
    /**
     * <code>required int32 name_id = 1;</code>
     */
    int getNameId();

    /**
     * <code>optional int32 super_name_id = 2;</code>
     */
    boolean hasSuperNameId();
    /**
     * <code>optional int32 super_name_id = 2;</code>
     */
    int getSuperNameId();

    /**
     * <code>repeated int32 interface_name_id = 4;</code>
     */
    java.util.List<java.lang.Integer> getInterfaceNameIdList();
    /**
     * <code>repeated int32 interface_name_id = 4;</code>
     */
    int getInterfaceNameIdCount();
    /**
     * <code>repeated int32 interface_name_id = 4;</code>
     */
    int getInterfaceNameId(int index);

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
     */
    boolean hasPostDeclarationBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getPostDeclarationBlock();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getPostDeclarationBlockOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ClassModel}
   */
  public static final class ClassModel extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.ClassModel)
      ClassModelOrBuilder {
    // Use ClassModel.newBuilder() to construct.
    private ClassModel(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private ClassModel(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final ClassModel defaultInstance;
    public static ClassModel getDefaultInstance() {
      return defaultInstance;
    }

    public ClassModel getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private ClassModel(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              nameId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              superNameId_ = input.readInt32();
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = postDeclarationBlock_.toBuilder();
              }
              postDeclarationBlock_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(postDeclarationBlock_);
                postDeclarationBlock_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
            case 32: {
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
                interfaceNameId_ = new java.util.ArrayList<java.lang.Integer>();
                mutable_bitField0_ |= 0x00000004;
              }
              interfaceNameId_.add(input.readInt32());
              break;
            }
            case 34: {
              int length = input.readRawVarint32();
              int limit = input.pushLimit(length);
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) {
                interfaceNameId_ = new java.util.ArrayList<java.lang.Integer>();
                mutable_bitField0_ |= 0x00000004;
              }
              while (input.getBytesUntilLimit() > 0) {
                interfaceNameId_.add(input.readInt32());
              }
              input.popLimit(limit);
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
          interfaceNameId_ = java.util.Collections.unmodifiableList(interfaceNameId_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<ClassModel> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<ClassModel>() {
      public ClassModel parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new ClassModel(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<ClassModel> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int NAME_ID_FIELD_NUMBER = 1;
    private int nameId_;
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public boolean hasNameId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 name_id = 1;</code>
     */
    public int getNameId() {
      return nameId_;
    }

    public static final int SUPER_NAME_ID_FIELD_NUMBER = 2;
    private int superNameId_;
    /**
     * <code>optional int32 super_name_id = 2;</code>
     */
    public boolean hasSuperNameId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 super_name_id = 2;</code>
     */
    public int getSuperNameId() {
      return superNameId_;
    }

    public static final int INTERFACE_NAME_ID_FIELD_NUMBER = 4;
    private java.util.List<java.lang.Integer> interfaceNameId_;
    /**
     * <code>repeated int32 interface_name_id = 4;</code>
     */
    public java.util.List<java.lang.Integer>
        getInterfaceNameIdList() {
      return interfaceNameId_;
    }
    /**
     * <code>repeated int32 interface_name_id = 4;</code>
     */
    public int getInterfaceNameIdCount() {
      return interfaceNameId_.size();
    }
    /**
     * <code>repeated int32 interface_name_id = 4;</code>
     */
    public int getInterfaceNameId(int index) {
      return interfaceNameId_.get(index);
    }

    public static final int POST_DECLARATION_BLOCK_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock postDeclarationBlock_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
     */
    public boolean hasPostDeclarationBlock() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getPostDeclarationBlock() {
      return postDeclarationBlock_;
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getPostDeclarationBlockOrBuilder() {
      return postDeclarationBlock_;
    }

    private void initFields() {
      nameId_ = 0;
      superNameId_ = 0;
      interfaceNameId_ = java.util.Collections.emptyList();
      postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasNameId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasPostDeclarationBlock()) {
        if (!getPostDeclarationBlock().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, superNameId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, postDeclarationBlock_);
      }
      for (int i = 0; i < interfaceNameId_.size(); i++) {
        output.writeInt32(4, interfaceNameId_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, nameId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, superNameId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, postDeclarationBlock_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < interfaceNameId_.size(); i++) {
          dataSize += org.jetbrains.kotlin.protobuf.CodedOutputStream
            .computeInt32SizeNoTag(interfaceNameId_.get(i));
        }
        size += dataSize;
        size += 1 * getInterfaceNameIdList().size();
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.ClassModel}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.ClassModel)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModelOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getPostDeclarationBlockFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        nameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        superNameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        interfaceNameId_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000004);
        if (postDeclarationBlockBuilder_ == null) {
          postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
        } else {
          postDeclarationBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nameId_ = nameId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.superNameId_ = superNameId_;
        if (((bitField0_ & 0x00000004) == 0x00000004)) {
          interfaceNameId_ = java.util.Collections.unmodifiableList(interfaceNameId_);
          bitField0_ = (bitField0_ & ~0x00000004);
        }
        result.interfaceNameId_ = interfaceNameId_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        if (postDeclarationBlockBuilder_ == null) {
          result.postDeclarationBlock_ = postDeclarationBlock_;
        } else {
          result.postDeclarationBlock_ = postDeclarationBlockBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel.getDefaultInstance()) return this;
        if (other.hasNameId()) {
          setNameId(other.getNameId());
        }
        if (other.hasSuperNameId()) {
          setSuperNameId(other.getSuperNameId());
        }
        if (!other.interfaceNameId_.isEmpty()) {
          if (interfaceNameId_.isEmpty()) {
            interfaceNameId_ = other.interfaceNameId_;
            bitField0_ = (bitField0_ & ~0x00000004);
          } else {
            ensureInterfaceNameIdIsMutable();
            interfaceNameId_.addAll(other.interfaceNameId_);
          }
          onChanged();
        }
        if (other.hasPostDeclarationBlock()) {
          mergePostDeclarationBlock(other.getPostDeclarationBlock());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasNameId()) {
          
          return false;
        }
        if (hasPostDeclarationBlock()) {
          if (!getPostDeclarationBlock().isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ClassModel) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int nameId_ ;
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public boolean hasNameId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public int getNameId() {
        return nameId_;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder setNameId(int value) {
        bitField0_ |= 0x00000001;
        nameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 name_id = 1;</code>
       */
      public Builder clearNameId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nameId_ = 0;
        onChanged();
        return this;
      }

      private int superNameId_ ;
      /**
       * <code>optional int32 super_name_id = 2;</code>
       */
      public boolean hasSuperNameId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 super_name_id = 2;</code>
       */
      public int getSuperNameId() {
        return superNameId_;
      }
      /**
       * <code>optional int32 super_name_id = 2;</code>
       */
      public Builder setSuperNameId(int value) {
        bitField0_ |= 0x00000002;
        superNameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 super_name_id = 2;</code>
       */
      public Builder clearSuperNameId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        superNameId_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> interfaceNameId_ = java.util.Collections.emptyList();
      private void ensureInterfaceNameIdIsMutable() {
        if (!((bitField0_ & 0x00000004) == 0x00000004)) {
          interfaceNameId_ = new java.util.ArrayList<java.lang.Integer>(interfaceNameId_);
          bitField0_ |= 0x00000004;
         }
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public java.util.List<java.lang.Integer>
          getInterfaceNameIdList() {
        return java.util.Collections.unmodifiableList(interfaceNameId_);
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public int getInterfaceNameIdCount() {
        return interfaceNameId_.size();
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public int getInterfaceNameId(int index) {
        return interfaceNameId_.get(index);
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public Builder setInterfaceNameId(
          int index, int value) {
        ensureInterfaceNameIdIsMutable();
        interfaceNameId_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public Builder addInterfaceNameId(int value) {
        ensureInterfaceNameIdIsMutable();
        interfaceNameId_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public Builder addAllInterfaceNameId(
          java.lang.Iterable<? extends java.lang.Integer> values) {
        ensureInterfaceNameIdIsMutable();
        org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
            values, interfaceNameId_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 interface_name_id = 4;</code>
       */
      public Builder clearInterfaceNameId() {
        interfaceNameId_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000004);
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> postDeclarationBlockBuilder_;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public boolean hasPostDeclarationBlock() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock getPostDeclarationBlock() {
        if (postDeclarationBlockBuilder_ == null) {
          return postDeclarationBlock_;
        } else {
          return postDeclarationBlockBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public Builder setPostDeclarationBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (postDeclarationBlockBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          postDeclarationBlock_ = value;
          onChanged();
        } else {
          postDeclarationBlockBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public Builder setPostDeclarationBlock(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder builderForValue) {
        if (postDeclarationBlockBuilder_ == null) {
          postDeclarationBlock_ = builderForValue.build();
          onChanged();
        } else {
          postDeclarationBlockBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public Builder mergePostDeclarationBlock(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock value) {
        if (postDeclarationBlockBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008) &&
              postDeclarationBlock_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance()) {
            postDeclarationBlock_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.newBuilder(postDeclarationBlock_).mergeFrom(value).buildPartial();
          } else {
            postDeclarationBlock_ = value;
          }
          onChanged();
        } else {
          postDeclarationBlockBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public Builder clearPostDeclarationBlock() {
        if (postDeclarationBlockBuilder_ == null) {
          postDeclarationBlock_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.getDefaultInstance();
          onChanged();
        } else {
          postDeclarationBlockBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder getPostDeclarationBlockBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getPostDeclarationBlockFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder getPostDeclarationBlockOrBuilder() {
        if (postDeclarationBlockBuilder_ != null) {
          return postDeclarationBlockBuilder_.getMessageOrBuilder();
        } else {
          return postDeclarationBlock_;
        }
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.GlobalBlock post_declaration_block = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder> 
          getPostDeclarationBlockFieldBuilder() {
        if (postDeclarationBlockBuilder_ == null) {
          postDeclarationBlockBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlock.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.GlobalBlockOrBuilder>(
                  getPostDeclarationBlock(),
                  getParentForChildren(),
                  isClean());
          postDeclarationBlock_ = null;
        }
        return postDeclarationBlockBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.ClassModel)
    }

    static {
      defaultInstance = new ClassModel(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.ClassModel)
  }

  public interface InlineModuleOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.InlineModule)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required int32 signature_id = 1;</code>
     */
    boolean hasSignatureId();
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    int getSignatureId();

    /**
     * <code>required int32 expression_id = 2;</code>
     */
    boolean hasExpressionId();
    /**
     * <code>required int32 expression_id = 2;</code>
     */
    int getExpressionId();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.InlineModule}
   */
  public static final class InlineModule extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.InlineModule)
      InlineModuleOrBuilder {
    // Use InlineModule.newBuilder() to construct.
    private InlineModule(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private InlineModule(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final InlineModule defaultInstance;
    public static InlineModule getDefaultInstance() {
      return defaultInstance;
    }

    public InlineModule getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private InlineModule(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              signatureId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              expressionId_ = input.readInt32();
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<InlineModule> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<InlineModule>() {
      public InlineModule parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new InlineModule(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<InlineModule> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int SIGNATURE_ID_FIELD_NUMBER = 1;
    private int signatureId_;
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    public boolean hasSignatureId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int32 signature_id = 1;</code>
     */
    public int getSignatureId() {
      return signatureId_;
    }

    public static final int EXPRESSION_ID_FIELD_NUMBER = 2;
    private int expressionId_;
    /**
     * <code>required int32 expression_id = 2;</code>
     */
    public boolean hasExpressionId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int32 expression_id = 2;</code>
     */
    public int getExpressionId() {
      return expressionId_;
    }

    private void initFields() {
      signatureId_ = 0;
      expressionId_ = 0;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasSignatureId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasExpressionId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt32(1, signatureId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, expressionId_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(1, signatureId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, expressionId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.InlineModule}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.InlineModule)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModuleOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        signatureId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        expressionId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.signatureId_ = signatureId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.expressionId_ = expressionId_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule.getDefaultInstance()) return this;
        if (other.hasSignatureId()) {
          setSignatureId(other.getSignatureId());
        }
        if (other.hasExpressionId()) {
          setExpressionId(other.getExpressionId());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasSignatureId()) {
          
          return false;
        }
        if (!hasExpressionId()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.InlineModule) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int signatureId_ ;
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public boolean hasSignatureId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public int getSignatureId() {
        return signatureId_;
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public Builder setSignatureId(int value) {
        bitField0_ |= 0x00000001;
        signatureId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 signature_id = 1;</code>
       */
      public Builder clearSignatureId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        signatureId_ = 0;
        onChanged();
        return this;
      }

      private int expressionId_ ;
      /**
       * <code>required int32 expression_id = 2;</code>
       */
      public boolean hasExpressionId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int32 expression_id = 2;</code>
       */
      public int getExpressionId() {
        return expressionId_;
      }
      /**
       * <code>required int32 expression_id = 2;</code>
       */
      public Builder setExpressionId(int value) {
        bitField0_ |= 0x00000002;
        expressionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int32 expression_id = 2;</code>
       */
      public Builder clearExpressionId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        expressionId_ = 0;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.InlineModule)
    }

    static {
      defaultInstance = new InlineModule(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.InlineModule)
  }

  public interface StringTableOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.StringTable)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated string entry = 1;</code>
     */
    org.jetbrains.kotlin.protobuf.ProtocolStringList
        getEntryList();
    /**
     * <code>repeated string entry = 1;</code>
     */
    int getEntryCount();
    /**
     * <code>repeated string entry = 1;</code>
     */
    java.lang.String getEntry(int index);
    /**
     * <code>repeated string entry = 1;</code>
     */
    org.jetbrains.kotlin.protobuf.ByteString
        getEntryBytes(int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.StringTable}
   */
  public static final class StringTable extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.StringTable)
      StringTableOrBuilder {
    // Use StringTable.newBuilder() to construct.
    private StringTable(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private StringTable(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final StringTable defaultInstance;
    public static StringTable getDefaultInstance() {
      return defaultInstance;
    }

    public StringTable getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private StringTable(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.protobuf.ByteString bs = input.readBytes();
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                entry_ = new org.jetbrains.kotlin.protobuf.LazyStringArrayList();
                mutable_bitField0_ |= 0x00000001;
              }
              entry_.add(bs);
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = entry_.getUnmodifiableView();
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<StringTable> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<StringTable>() {
      public StringTable parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new StringTable(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<StringTable> getParserForType() {
      return PARSER;
    }

    public static final int ENTRY_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.protobuf.LazyStringList entry_;
    /**
     * <code>repeated string entry = 1;</code>
     */
    public org.jetbrains.kotlin.protobuf.ProtocolStringList
        getEntryList() {
      return entry_;
    }
    /**
     * <code>repeated string entry = 1;</code>
     */
    public int getEntryCount() {
      return entry_.size();
    }
    /**
     * <code>repeated string entry = 1;</code>
     */
    public java.lang.String getEntry(int index) {
      return entry_.get(index);
    }
    /**
     * <code>repeated string entry = 1;</code>
     */
    public org.jetbrains.kotlin.protobuf.ByteString
        getEntryBytes(int index) {
      return entry_.getByteString(index);
    }

    private void initFields() {
      entry_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < entry_.size(); i++) {
        output.writeBytes(1, entry_.getByteString(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      {
        int dataSize = 0;
        for (int i = 0; i < entry_.size(); i++) {
          dataSize += org.jetbrains.kotlin.protobuf.CodedOutputStream
            .computeBytesSizeNoTag(entry_.getByteString(i));
        }
        size += dataSize;
        size += 1 * getEntryList().size();
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.StringTable}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.StringTable)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        entry_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable(this);
        int from_bitField0_ = bitField0_;
        if (((bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = entry_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000001);
        }
        result.entry_ = entry_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance()) return this;
        if (!other.entry_.isEmpty()) {
          if (entry_.isEmpty()) {
            entry_ = other.entry_;
            bitField0_ = (bitField0_ & ~0x00000001);
          } else {
            ensureEntryIsMutable();
            entry_.addAll(other.entry_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.protobuf.LazyStringList entry_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
      private void ensureEntryIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = new org.jetbrains.kotlin.protobuf.LazyStringArrayList(entry_);
          bitField0_ |= 0x00000001;
         }
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public org.jetbrains.kotlin.protobuf.ProtocolStringList
          getEntryList() {
        return entry_.getUnmodifiableView();
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public int getEntryCount() {
        return entry_.size();
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public java.lang.String getEntry(int index) {
        return entry_.get(index);
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public org.jetbrains.kotlin.protobuf.ByteString
          getEntryBytes(int index) {
        return entry_.getByteString(index);
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public Builder setEntry(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureEntryIsMutable();
        entry_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public Builder addEntry(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureEntryIsMutable();
        entry_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public Builder addAllEntry(
          java.lang.Iterable<java.lang.String> values) {
        ensureEntryIsMutable();
        org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
            values, entry_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public Builder clearEntry() {
        entry_ = org.jetbrains.kotlin.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string entry = 1;</code>
       */
      public Builder addEntryBytes(
          org.jetbrains.kotlin.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureEntryIsMutable();
        entry_.add(value);
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.StringTable)
    }

    static {
      defaultInstance = new StringTable(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.StringTable)
  }

  public interface NameTableOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.NameTable)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name> 
        getEntryList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name getEntry(int index);
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    int getEntryCount();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder> 
        getEntryOrBuilderList();
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder getEntryOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NameTable}
   */
  public static final class NameTable extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.NameTable)
      NameTableOrBuilder {
    // Use NameTable.newBuilder() to construct.
    private NameTable(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private NameTable(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final NameTable defaultInstance;
    public static NameTable getDefaultInstance() {
      return defaultInstance;
    }

    public NameTable getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private NameTable(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                entry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name>();
                mutable_bitField0_ |= 0x00000001;
              }
              entry_.add(input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = java.util.Collections.unmodifiableList(entry_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<NameTable> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<NameTable>() {
      public NameTable parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new NameTable(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<NameTable> getParserForType() {
      return PARSER;
    }

    public static final int ENTRY_FIELD_NUMBER = 1;
    private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name> entry_;
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name> getEntryList() {
      return entry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder> 
        getEntryOrBuilderList() {
      return entry_;
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    public int getEntryCount() {
      return entry_.size();
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name getEntry(int index) {
      return entry_.get(index);
    }
    /**
     * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder getEntryOrBuilder(
        int index) {
      return entry_.get(index);
    }

    private void initFields() {
      entry_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getEntryCount(); i++) {
        if (!getEntry(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      for (int i = 0; i < entry_.size(); i++) {
        output.writeMessage(1, entry_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < entry_.size(); i++) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, entry_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.NameTable}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.NameTable)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getEntryFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (entryBuilder_ == null) {
          entry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          entryBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable(this);
        int from_bitField0_ = bitField0_;
        if (entryBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001)) {
            entry_ = java.util.Collections.unmodifiableList(entry_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.entry_ = entry_;
        } else {
          result.entry_ = entryBuilder_.build();
        }
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance()) return this;
        if (entryBuilder_ == null) {
          if (!other.entry_.isEmpty()) {
            if (entry_.isEmpty()) {
              entry_ = other.entry_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureEntryIsMutable();
              entry_.addAll(other.entry_);
            }
            onChanged();
          }
        } else {
          if (!other.entry_.isEmpty()) {
            if (entryBuilder_.isEmpty()) {
              entryBuilder_.dispose();
              entryBuilder_ = null;
              entry_ = other.entry_;
              bitField0_ = (bitField0_ & ~0x00000001);
              entryBuilder_ = 
                org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getEntryFieldBuilder() : null;
            } else {
              entryBuilder_.addAllMessages(other.entry_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        for (int i = 0; i < getEntryCount(); i++) {
          if (!getEntry(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name> entry_ =
        java.util.Collections.emptyList();
      private void ensureEntryIsMutable() {
        if (!((bitField0_ & 0x00000001) == 0x00000001)) {
          entry_ = new java.util.ArrayList<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name>(entry_);
          bitField0_ |= 0x00000001;
         }
      }

      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder> entryBuilder_;

      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name> getEntryList() {
        if (entryBuilder_ == null) {
          return java.util.Collections.unmodifiableList(entry_);
        } else {
          return entryBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public int getEntryCount() {
        if (entryBuilder_ == null) {
          return entry_.size();
        } else {
          return entryBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name getEntry(int index) {
        if (entryBuilder_ == null) {
          return entry_.get(index);
        } else {
          return entryBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder setEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.set(index, value);
          onChanged();
        } else {
          entryBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder setEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.set(index, builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder addEntry(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.add(value);
          onChanged();
        } else {
          entryBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder addEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name value) {
        if (entryBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureEntryIsMutable();
          entry_.add(index, value);
          onChanged();
        } else {
          entryBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder addEntry(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.add(builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder addEntry(
          int index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder builderForValue) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.add(index, builderForValue.build());
          onChanged();
        } else {
          entryBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder addAllEntry(
          java.lang.Iterable<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name> values) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll(
              values, entry_);
          onChanged();
        } else {
          entryBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder clearEntry() {
        if (entryBuilder_ == null) {
          entry_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          entryBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public Builder removeEntry(int index) {
        if (entryBuilder_ == null) {
          ensureEntryIsMutable();
          entry_.remove(index);
          onChanged();
        } else {
          entryBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder getEntryBuilder(
          int index) {
        return getEntryFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder getEntryOrBuilder(
          int index) {
        if (entryBuilder_ == null) {
          return entry_.get(index);  } else {
          return entryBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public java.util.List<? extends org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder> 
           getEntryOrBuilderList() {
        if (entryBuilder_ != null) {
          return entryBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(entry_);
        }
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder addEntryBuilder() {
        return getEntryFieldBuilder().addBuilder(
            org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder addEntryBuilder(
          int index) {
        return getEntryFieldBuilder().addBuilder(
            index, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.getDefaultInstance());
      }
      /**
       * <code>repeated .org.jetbrains.kotlin.serialization.js.ast.Name entry = 1;</code>
       */
      public java.util.List<org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder> 
           getEntryBuilderList() {
        return getEntryFieldBuilder().getBuilderList();
      }
      private org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder> 
          getEntryFieldBuilder() {
        if (entryBuilder_ == null) {
          entryBuilder_ = new org.jetbrains.kotlin.protobuf.RepeatedFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder>(
                  entry_,
                  ((bitField0_ & 0x00000001) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          entry_ = null;
        }
        return entryBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.NameTable)
    }

    static {
      defaultInstance = new NameTable(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.NameTable)
  }

  public interface NameOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Name)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required bool temporary = 1;</code>
     */
    boolean hasTemporary();
    /**
     * <code>required bool temporary = 1;</code>
     */
    boolean getTemporary();

    /**
     * <code>optional int32 identifier = 2;</code>
     */
    boolean hasIdentifier();
    /**
     * <code>optional int32 identifier = 2;</code>
     */
    int getIdentifier();

    /**
     * <code>optional int32 local_name_id = 3;</code>
     */
    boolean hasLocalNameId();
    /**
     * <code>optional int32 local_name_id = 3;</code>
     */
    int getLocalNameId();

    /**
     * <code>optional bool imported = 4 [default = false];</code>
     */
    boolean hasImported();
    /**
     * <code>optional bool imported = 4 [default = false];</code>
     */
    boolean getImported();

    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
     */
    boolean hasSpecialFunction();
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction getSpecialFunction();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Name}
   */
  public static final class Name extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Name)
      NameOrBuilder {
    // Use Name.newBuilder() to construct.
    private Name(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Name(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Name defaultInstance;
    public static Name getDefaultInstance() {
      return defaultInstance;
    }

    public Name getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Name(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              temporary_ = input.readBool();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              identifier_ = input.readInt32();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              localNameId_ = input.readInt32();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              imported_ = input.readBool();
              break;
            }
            case 40: {
              int rawValue = input.readEnum();
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction value = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(5, rawValue);
              } else {
                bitField0_ |= 0x00000010;
                specialFunction_ = value;
              }
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Name> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Name>() {
      public Name parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Name(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Name> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int TEMPORARY_FIELD_NUMBER = 1;
    private boolean temporary_;
    /**
     * <code>required bool temporary = 1;</code>
     */
    public boolean hasTemporary() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required bool temporary = 1;</code>
     */
    public boolean getTemporary() {
      return temporary_;
    }

    public static final int IDENTIFIER_FIELD_NUMBER = 2;
    private int identifier_;
    /**
     * <code>optional int32 identifier = 2;</code>
     */
    public boolean hasIdentifier() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 identifier = 2;</code>
     */
    public int getIdentifier() {
      return identifier_;
    }

    public static final int LOCAL_NAME_ID_FIELD_NUMBER = 3;
    private int localNameId_;
    /**
     * <code>optional int32 local_name_id = 3;</code>
     */
    public boolean hasLocalNameId() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int32 local_name_id = 3;</code>
     */
    public int getLocalNameId() {
      return localNameId_;
    }

    public static final int IMPORTED_FIELD_NUMBER = 4;
    private boolean imported_;
    /**
     * <code>optional bool imported = 4 [default = false];</code>
     */
    public boolean hasImported() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional bool imported = 4 [default = false];</code>
     */
    public boolean getImported() {
      return imported_;
    }

    public static final int SPECIAL_FUNCTION_FIELD_NUMBER = 5;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction specialFunction_;
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
     */
    public boolean hasSpecialFunction() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction getSpecialFunction() {
      return specialFunction_;
    }

    private void initFields() {
      temporary_ = false;
      identifier_ = 0;
      localNameId_ = 0;
      imported_ = false;
      specialFunction_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction.DEFINE_INLINE_FUNCTION;
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasTemporary()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeBool(1, temporary_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, identifier_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(3, localNameId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeBool(4, imported_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeEnum(5, specialFunction_.getNumber());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(1, temporary_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(2, identifier_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeInt32Size(3, localNameId_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeBoolSize(4, imported_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeEnumSize(5, specialFunction_.getNumber());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Name}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Name)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        temporary_ = false;
        bitField0_ = (bitField0_ & ~0x00000001);
        identifier_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        localNameId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        imported_ = false;
        bitField0_ = (bitField0_ & ~0x00000008);
        specialFunction_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction.DEFINE_INLINE_FUNCTION;
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.temporary_ = temporary_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.identifier_ = identifier_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.localNameId_ = localNameId_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.imported_ = imported_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.specialFunction_ = specialFunction_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name.getDefaultInstance()) return this;
        if (other.hasTemporary()) {
          setTemporary(other.getTemporary());
        }
        if (other.hasIdentifier()) {
          setIdentifier(other.getIdentifier());
        }
        if (other.hasLocalNameId()) {
          setLocalNameId(other.getLocalNameId());
        }
        if (other.hasImported()) {
          setImported(other.getImported());
        }
        if (other.hasSpecialFunction()) {
          setSpecialFunction(other.getSpecialFunction());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTemporary()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Name) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private boolean temporary_ ;
      /**
       * <code>required bool temporary = 1;</code>
       */
      public boolean hasTemporary() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required bool temporary = 1;</code>
       */
      public boolean getTemporary() {
        return temporary_;
      }
      /**
       * <code>required bool temporary = 1;</code>
       */
      public Builder setTemporary(boolean value) {
        bitField0_ |= 0x00000001;
        temporary_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required bool temporary = 1;</code>
       */
      public Builder clearTemporary() {
        bitField0_ = (bitField0_ & ~0x00000001);
        temporary_ = false;
        onChanged();
        return this;
      }

      private int identifier_ ;
      /**
       * <code>optional int32 identifier = 2;</code>
       */
      public boolean hasIdentifier() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 identifier = 2;</code>
       */
      public int getIdentifier() {
        return identifier_;
      }
      /**
       * <code>optional int32 identifier = 2;</code>
       */
      public Builder setIdentifier(int value) {
        bitField0_ |= 0x00000002;
        identifier_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 identifier = 2;</code>
       */
      public Builder clearIdentifier() {
        bitField0_ = (bitField0_ & ~0x00000002);
        identifier_ = 0;
        onChanged();
        return this;
      }

      private int localNameId_ ;
      /**
       * <code>optional int32 local_name_id = 3;</code>
       */
      public boolean hasLocalNameId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 local_name_id = 3;</code>
       */
      public int getLocalNameId() {
        return localNameId_;
      }
      /**
       * <code>optional int32 local_name_id = 3;</code>
       */
      public Builder setLocalNameId(int value) {
        bitField0_ |= 0x00000004;
        localNameId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 local_name_id = 3;</code>
       */
      public Builder clearLocalNameId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        localNameId_ = 0;
        onChanged();
        return this;
      }

      private boolean imported_ ;
      /**
       * <code>optional bool imported = 4 [default = false];</code>
       */
      public boolean hasImported() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional bool imported = 4 [default = false];</code>
       */
      public boolean getImported() {
        return imported_;
      }
      /**
       * <code>optional bool imported = 4 [default = false];</code>
       */
      public Builder setImported(boolean value) {
        bitField0_ |= 0x00000008;
        imported_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool imported = 4 [default = false];</code>
       */
      public Builder clearImported() {
        bitField0_ = (bitField0_ & ~0x00000008);
        imported_ = false;
        onChanged();
        return this;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction specialFunction_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction.DEFINE_INLINE_FUNCTION;
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
       */
      public boolean hasSpecialFunction() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction getSpecialFunction() {
        return specialFunction_;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
       */
      public Builder setSpecialFunction(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000010;
        specialFunction_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional .org.jetbrains.kotlin.serialization.js.ast.SpecialFunction special_function = 5;</code>
       */
      public Builder clearSpecialFunction() {
        bitField0_ = (bitField0_ & ~0x00000010);
        specialFunction_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.SpecialFunction.DEFINE_INLINE_FUNCTION;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Name)
    }

    static {
      defaultInstance = new Name(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Name)
  }

  public interface ChunkOrBuilder extends
      // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.js.ast.Chunk)
      org.jetbrains.kotlin.protobuf.MessageOrBuilder {

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
     */
    boolean hasStringTable();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable getStringTable();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder getStringTableOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
     */
    boolean hasNameTable();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable getNameTable();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder getNameTableOrBuilder();

    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
     */
    boolean hasFragment();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment getFragment();
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
     */
    org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder getFragmentOrBuilder();
  }
  /**
   * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Chunk}
   */
  public static final class Chunk extends
      org.jetbrains.kotlin.protobuf.GeneratedMessage implements
      // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.serialization.js.ast.Chunk)
      ChunkOrBuilder {
    // Use Chunk.newBuilder() to construct.
    private Chunk(org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Chunk(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Chunk defaultInstance;
    public static Chunk getDefaultInstance() {
      return defaultInstance;
    }

    public Chunk getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final org.jetbrains.kotlin.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final org.jetbrains.kotlin.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Chunk(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      org.jetbrains.kotlin.protobuf.UnknownFieldSet.Builder unknownFields =
          org.jetbrains.kotlin.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 10: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = stringTable_.toBuilder();
              }
              stringTable_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(stringTable_);
                stringTable_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = nameTable_.toBuilder();
              }
              nameTable_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(nameTable_);
                nameTable_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 26: {
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = fragment_.toBuilder();
              }
              fragment_ = input.readMessage(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(fragment_);
                fragment_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
          }
        }
      } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_descriptor;
    }

    protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.Builder.class);
    }

    public static org.jetbrains.kotlin.protobuf.Parser<Chunk> PARSER =
        new org.jetbrains.kotlin.protobuf.AbstractParser<Chunk>() {
      public Chunk parsePartialFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
        return new Chunk(input, extensionRegistry);
      }
    };

    @java.lang.Override
    public org.jetbrains.kotlin.protobuf.Parser<Chunk> getParserForType() {
      return PARSER;
    }

    private int bitField0_;
    public static final int STRING_TABLE_FIELD_NUMBER = 1;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable stringTable_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
     */
    public boolean hasStringTable() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable getStringTable() {
      return stringTable_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder getStringTableOrBuilder() {
      return stringTable_;
    }

    public static final int NAME_TABLE_FIELD_NUMBER = 2;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable nameTable_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
     */
    public boolean hasNameTable() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable getNameTable() {
      return nameTable_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder getNameTableOrBuilder() {
      return nameTable_;
    }

    public static final int FRAGMENT_FIELD_NUMBER = 3;
    private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment fragment_;
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
     */
    public boolean hasFragment() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment getFragment() {
      return fragment_;
    }
    /**
     * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
     */
    public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder getFragmentOrBuilder() {
      return fragment_;
    }

    private void initFields() {
      stringTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance();
      nameTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance();
      fragment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasStringTable()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasNameTable()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasFragment()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getNameTable().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!getFragment().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeMessage(1, stringTable_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, nameTable_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, fragment_);
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(1, stringTable_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(2, nameTable_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += org.jetbrains.kotlin.protobuf.CodedOutputStream
          .computeMessageSize(3, fragment_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(
        org.jetbrains.kotlin.protobuf.ByteString data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(byte[] data)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(
        byte[] data,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseDelimitedFrom(
        java.io.InputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parseFrom(
        org.jetbrains.kotlin.protobuf.CodedInputStream input,
        org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code org.jetbrains.kotlin.serialization.js.ast.Chunk}
     */
    public static final class Builder extends
        org.jetbrains.kotlin.protobuf.GeneratedMessage.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.serialization.js.ast.Chunk)
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.ChunkOrBuilder {
      public static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_descriptor;
      }

      protected org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.class, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.Builder.class);
      }

      // Construct using org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          org.jetbrains.kotlin.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (org.jetbrains.kotlin.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getStringTableFieldBuilder();
          getNameTableFieldBuilder();
          getFragmentFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        if (stringTableBuilder_ == null) {
          stringTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance();
        } else {
          stringTableBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (nameTableBuilder_ == null) {
          nameTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance();
        } else {
          nameTableBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (fragmentBuilder_ == null) {
          fragment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance();
        } else {
          fragmentBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_descriptor;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk getDefaultInstanceForType() {
        return org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.getDefaultInstance();
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk build() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk buildPartial() {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk result = new org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (stringTableBuilder_ == null) {
          result.stringTable_ = stringTable_;
        } else {
          result.stringTable_ = stringTableBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (nameTableBuilder_ == null) {
          result.nameTable_ = nameTable_;
        } else {
          result.nameTable_ = nameTableBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (fragmentBuilder_ == null) {
          result.fragment_ = fragment_;
        } else {
          result.fragment_ = fragmentBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(org.jetbrains.kotlin.protobuf.Message other) {
        if (other instanceof org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk) {
          return mergeFrom((org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk other) {
        if (other == org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk.getDefaultInstance()) return this;
        if (other.hasStringTable()) {
          mergeStringTable(other.getStringTable());
        }
        if (other.hasNameTable()) {
          mergeNameTable(other.getNameTable());
        }
        if (other.hasFragment()) {
          mergeFragment(other.getFragment());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasStringTable()) {
          
          return false;
        }
        if (!hasNameTable()) {
          
          return false;
        }
        if (!hasFragment()) {
          
          return false;
        }
        if (!getNameTable().isInitialized()) {
          
          return false;
        }
        if (!getFragment().isInitialized()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          org.jetbrains.kotlin.protobuf.CodedInputStream input,
          org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Chunk) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable stringTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder> stringTableBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public boolean hasStringTable() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable getStringTable() {
        if (stringTableBuilder_ == null) {
          return stringTable_;
        } else {
          return stringTableBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public Builder setStringTable(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable value) {
        if (stringTableBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          stringTable_ = value;
          onChanged();
        } else {
          stringTableBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public Builder setStringTable(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder builderForValue) {
        if (stringTableBuilder_ == null) {
          stringTable_ = builderForValue.build();
          onChanged();
        } else {
          stringTableBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public Builder mergeStringTable(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable value) {
        if (stringTableBuilder_ == null) {
          if (((bitField0_ & 0x00000001) == 0x00000001) &&
              stringTable_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance()) {
            stringTable_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.newBuilder(stringTable_).mergeFrom(value).buildPartial();
          } else {
            stringTable_ = value;
          }
          onChanged();
        } else {
          stringTableBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public Builder clearStringTable() {
        if (stringTableBuilder_ == null) {
          stringTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.getDefaultInstance();
          onChanged();
        } else {
          stringTableBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder getStringTableBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getStringTableFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder getStringTableOrBuilder() {
        if (stringTableBuilder_ != null) {
          return stringTableBuilder_.getMessageOrBuilder();
        } else {
          return stringTable_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.StringTable string_table = 1;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder> 
          getStringTableFieldBuilder() {
        if (stringTableBuilder_ == null) {
          stringTableBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTable.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.StringTableOrBuilder>(
                  getStringTable(),
                  getParentForChildren(),
                  isClean());
          stringTable_ = null;
        }
        return stringTableBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable nameTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder> nameTableBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public boolean hasNameTable() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable getNameTable() {
        if (nameTableBuilder_ == null) {
          return nameTable_;
        } else {
          return nameTableBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public Builder setNameTable(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable value) {
        if (nameTableBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          nameTable_ = value;
          onChanged();
        } else {
          nameTableBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public Builder setNameTable(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder builderForValue) {
        if (nameTableBuilder_ == null) {
          nameTable_ = builderForValue.build();
          onChanged();
        } else {
          nameTableBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public Builder mergeNameTable(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable value) {
        if (nameTableBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002) &&
              nameTable_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance()) {
            nameTable_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.newBuilder(nameTable_).mergeFrom(value).buildPartial();
          } else {
            nameTable_ = value;
          }
          onChanged();
        } else {
          nameTableBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public Builder clearNameTable() {
        if (nameTableBuilder_ == null) {
          nameTable_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.getDefaultInstance();
          onChanged();
        } else {
          nameTableBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder getNameTableBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getNameTableFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder getNameTableOrBuilder() {
        if (nameTableBuilder_ != null) {
          return nameTableBuilder_.getMessageOrBuilder();
        } else {
          return nameTable_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.NameTable name_table = 2;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder> 
          getNameTableFieldBuilder() {
        if (nameTableBuilder_ == null) {
          nameTableBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTable.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.NameTableOrBuilder>(
                  getNameTable(),
                  getParentForChildren(),
                  isClean());
          nameTable_ = null;
        }
        return nameTableBuilder_;
      }

      private org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment fragment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance();
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder> fragmentBuilder_;
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public boolean hasFragment() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment getFragment() {
        if (fragmentBuilder_ == null) {
          return fragment_;
        } else {
          return fragmentBuilder_.getMessage();
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public Builder setFragment(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment value) {
        if (fragmentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          fragment_ = value;
          onChanged();
        } else {
          fragmentBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public Builder setFragment(
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder builderForValue) {
        if (fragmentBuilder_ == null) {
          fragment_ = builderForValue.build();
          onChanged();
        } else {
          fragmentBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public Builder mergeFragment(org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment value) {
        if (fragmentBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004) &&
              fragment_ != org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance()) {
            fragment_ =
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.newBuilder(fragment_).mergeFrom(value).buildPartial();
          } else {
            fragment_ = value;
          }
          onChanged();
        } else {
          fragmentBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public Builder clearFragment() {
        if (fragmentBuilder_ == null) {
          fragment_ = org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.getDefaultInstance();
          onChanged();
        } else {
          fragmentBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder getFragmentBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getFragmentFieldBuilder().getBuilder();
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      public org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder getFragmentOrBuilder() {
        if (fragmentBuilder_ != null) {
          return fragmentBuilder_.getMessageOrBuilder();
        } else {
          return fragment_;
        }
      }
      /**
       * <code>required .org.jetbrains.kotlin.serialization.js.ast.Fragment fragment = 3;</code>
       */
      private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
          org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder> 
          getFragmentFieldBuilder() {
        if (fragmentBuilder_ == null) {
          fragmentBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
              org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.Fragment.Builder, org.jetbrains.kotlin.serialization.js.ast.DebugJsAstProtoBuf.FragmentOrBuilder>(
                  getFragment(),
                  getParentForChildren(),
                  isClean());
          fragment_ = null;
        }
        return fragmentBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.serialization.js.ast.Chunk)
    }

    static {
      defaultInstance = new Chunk(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.serialization.js.ast.Chunk)
  }

  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_If_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_If_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_While_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_For_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_For_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_fieldAccessorTable;
  private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_descriptor;
  private static
    org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_fieldAccessorTable;

  public static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\'js/js.serializer/src/js-ast.debug.prot" +
      "o\022)org.jetbrains.kotlin.serialization.js" +
      ".ast\"0\n\010Location\022\021\n\tstartLine\030\001 \002(\005\022\021\n\ts" +
      "tartChar\030\002 \002(\005\"\306\r\n\nExpression\022\016\n\006fileId\030" +
      "\001 \001(\005\022E\n\010location\030\002 \001(\01323.org.jetbrains." +
      "kotlin.serialization.js.ast.Location\022\030\n\t" +
      "synthetic\030\003 \001(\010:\005false\022[\n\014side_effects\030\004" +
      " \001(\01626.org.jetbrains.kotlin.serializatio" +
      "n.js.ast.SideEffects:\rAFFECTS_STATE\022\023\n\013l" +
      "ocal_alias\030\005 \001(\005\022\037\n\025simple_name_referenc",
      "e\030\026 \001(\005H\000\022N\n\014this_literal\030\027 \001(\01326.org.je" +
      "tbrains.kotlin.serialization.js.ast.This" +
      "LiteralH\000\022N\n\014null_literal\030\030 \001(\01326.org.je" +
      "tbrains.kotlin.serialization.js.ast.Null" +
      "LiteralH\000\022N\n\014true_literal\030\031 \001(\01326.org.je" +
      "tbrains.kotlin.serialization.js.ast.True" +
      "LiteralH\000\022P\n\rfalse_literal\030\032 \001(\01327.org.j" +
      "etbrains.kotlin.serialization.js.ast.Fal" +
      "seLiteralH\000\022\030\n\016string_literal\030\033 \001(\005H\000\022S\n" +
      "\017reg_exp_literal\030\034 \001(\01328.org.jetbrains.k",
      "otlin.serialization.js.ast.RegExpLiteral" +
      "H\000\022\025\n\013int_literal\030\035 \001(\005H\000\022\030\n\016double_lite" +
      "ral\030\036 \001(\001H\000\022P\n\rarray_literal\030\037 \001(\01327.org" +
      ".jetbrains.kotlin.serialization.js.ast.A" +
      "rrayLiteralH\000\022R\n\016object_literal\030  \001(\01328." +
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.ObjectLiteralH\000\022G\n\010function\030! \001(\01323.or" +
      "g.jetbrains.kotlin.serialization.js.ast." +
      "FunctionH\000\022L\n\013doc_comment\030\" \001(\01325.org.je" +
      "tbrains.kotlin.serialization.js.ast.DocC",
      "ommentH\000\022L\n\006binary\030# \001(\0132:.org.jetbrains" +
      ".kotlin.serialization.js.ast.BinaryOpera" +
      "tionH\000\022J\n\005unary\030$ \001(\01329.org.jetbrains.ko" +
      "tlin.serialization.js.ast.UnaryOperation" +
      "H\000\022M\n\013conditional\030% \001(\01326.org.jetbrains." +
      "kotlin.serialization.js.ast.ConditionalH" +
      "\000\022N\n\014array_access\030& \001(\01326.org.jetbrains." +
      "kotlin.serialization.js.ast.ArrayAccessH" +
      "\000\022R\n\016name_reference\030\' \001(\01328.org.jetbrain" +
      "s.kotlin.serialization.js.ast.NameRefere",
      "nceH\000\022Z\n\022property_reference\030( \001(\0132<.org." +
      "jetbrains.kotlin.serialization.js.ast.Pr" +
      "opertyReferenceH\000\022K\n\ninvocation\030) \001(\01325." +
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.InvocationH\000\022Q\n\rinstantiation\030* \001(\01328." +
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.InstantiationH\000B\014\n\nexpression\"\r\n\013ThisL" +
      "iteral\"\r\n\013NullLiteral\"\r\n\013TrueLiteral\"\016\n\014" +
      "FalseLiteral\"C\n\rRegExpLiteral\022\031\n\021pattern" +
      "_string_id\030\001 \002(\005\022\027\n\017flags_string_id\030\002 \001(",
      "\005\"V\n\014ArrayLiteral\022F\n\007element\030\001 \003(\01325.org" +
      ".jetbrains.kotlin.serialization.js.ast.E" +
      "xpression\"v\n\rObjectLiteral\022L\n\005entry\030\001 \003(" +
      "\0132=.org.jetbrains.kotlin.serialization.j" +
      "s.ast.ObjectLiteralEntry\022\027\n\tmultiline\030\002 " +
      "\001(\010:\004true\"\236\001\n\022ObjectLiteralEntry\022B\n\003key\030" +
      "\001 \002(\01325.org.jetbrains.kotlin.serializati" +
      "on.js.ast.Expression\022D\n\005value\030\002 \002(\01325.or" +
      "g.jetbrains.kotlin.serialization.js.ast." +
      "Expression\"\276\001\n\010Function\022G\n\tparameter\030\001 \003",
      "(\01324.org.jetbrains.kotlin.serialization." +
      "js.ast.Parameter\022\017\n\007name_id\030\002 \001(\005\022B\n\004bod" +
      "y\030\003 \002(\01324.org.jetbrains.kotlin.serializa" +
      "tion.js.ast.Statement\022\024\n\005local\030\004 \001(\010:\005fa" +
      "lse\">\n\tParameter\022\017\n\007name_id\030\001 \002(\005\022 \n\021has" +
      "_default_value\030\002 \001(\010:\005false\"S\n\nDocCommen" +
      "t\022E\n\003tag\030\001 \003(\01328.org.jetbrains.kotlin.se" +
      "rialization.js.ast.DocCommentTag\"\221\001\n\rDoc" +
      "CommentTag\022\017\n\007name_id\030\001 \002(\005\022\031\n\017value_str" +
      "ing_id\030\002 \001(\005H\000\022K\n\nexpression\030\003 \001(\01325.org",
      ".jetbrains.kotlin.serialization.js.ast.E" +
      "xpressionH\000B\007\n\005value\"\207\005\n\017BinaryOperation" +
      "\022C\n\004left\030\001 \002(\01325.org.jetbrains.kotlin.se" +
      "rialization.js.ast.Expression\022D\n\005right\030\002" +
      " \002(\01325.org.jetbrains.kotlin.serializatio" +
      "n.js.ast.Expression\022M\n\004type\030\003 \002(\0162?.org." +
      "jetbrains.kotlin.serialization.js.ast.Bi" +
      "naryOperation.Type\"\231\003\n\004Type\022\007\n\003MUL\020\001\022\007\n\003" +
      "DIV\020\002\022\007\n\003MOD\020\003\022\007\n\003ADD\020\004\022\007\n\003SUB\020\005\022\007\n\003SHL\020" +
      "\006\022\007\n\003SHR\020\007\022\010\n\004SHRU\020\010\022\006\n\002LT\020\t\022\007\n\003LTE\020\n\022\006\n",
      "\002GT\020\013\022\007\n\003GTE\020\014\022\016\n\nINSTANCEOF\020\r\022\006\n\002IN\020\016\022\006" +
      "\n\002EQ\020\017\022\007\n\003NEQ\020\020\022\n\n\006REF_EQ\020\021\022\013\n\007REF_NEQ\020\022" +
      "\022\013\n\007BIT_AND\020\023\022\013\n\007BIT_XOR\020\024\022\n\n\006BIT_OR\020\025\022\007" +
      "\n\003AND\020\026\022\006\n\002OR\020\027\022\007\n\003ASG\020\030\022\013\n\007ASG_ADD\020\031\022\013\n" +
      "\007ASG_SUB\020\032\022\013\n\007ASG_MUL\020\033\022\013\n\007ASG_DIV\020\034\022\013\n\007" +
      "ASG_MOD\020\035\022\013\n\007ASG_SHL\020\036\022\013\n\007ASG_SHR\020\037\022\014\n\010A" +
      "SG_SHRU\020 \022\017\n\013ASG_BIT_AND\020!\022\016\n\nASG_BIT_OR" +
      "\020\"\022\017\n\013ASG_BIT_XOR\020#\022\t\n\005COMMA\020$\"\233\002\n\016Unary" +
      "Operation\022F\n\007operand\030\001 \002(\01325.org.jetbrai" +
      "ns.kotlin.serialization.js.ast.Expressio",
      "n\022L\n\004type\030\002 \002(\0162>.org.jetbrains.kotlin.s" +
      "erialization.js.ast.UnaryOperation.Type\022" +
      "\017\n\007postfix\030\003 \002(\010\"b\n\004Type\022\013\n\007BIT_NOT\020\001\022\007\n" +
      "\003DEC\020\002\022\n\n\006DELETE\020\003\022\007\n\003INC\020\004\022\007\n\003NEG\020\005\022\007\n\003" +
      "POS\020\006\022\007\n\003NOT\020\007\022\n\n\006TYPEOF\020\010\022\010\n\004VOID\020\t\"\375\001\n" +
      "\013Conditional\022N\n\017test_expression\030\001 \002(\01325." +
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.Expression\022N\n\017then_expression\030\002 \002(\01325." +
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.Expression\022N\n\017else_expression\030\003 \002(\01325.",
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.Expression\"\231\001\n\013ArrayAccess\022D\n\005array\030\001 " +
      "\002(\01325.org.jetbrains.kotlin.serialization" +
      ".js.ast.Expression\022D\n\005index\030\002 \002(\01325.org." +
      "jetbrains.kotlin.serialization.js.ast.Ex" +
      "pression\"\312\001\n\rNameReference\022\017\n\007name_id\030\001 " +
      "\002(\005\022H\n\tqualifier\030\002 \001(\01325.org.jetbrains.k" +
      "otlin.serialization.js.ast.Expression\022^\n" +
      "\017inline_strategy\030\003 \001(\01629.org.jetbrains.k" +
      "otlin.serialization.js.ast.InlineStrateg",
      "y:\nNOT_INLINE\"\320\001\n\021PropertyReference\022\021\n\ts" +
      "tring_id\030\001 \002(\005\022H\n\tqualifier\030\002 \001(\01325.org." +
      "jetbrains.kotlin.serialization.js.ast.Ex" +
      "pression\022^\n\017inline_strategy\030\003 \001(\01629.org." +
      "jetbrains.kotlin.serialization.js.ast.In" +
      "lineStrategy:\nNOT_INLINE\"\377\001\n\nInvocation\022" +
      "H\n\tqualifier\030\001 \002(\01325.org.jetbrains.kotli" +
      "n.serialization.js.ast.Expression\022G\n\010arg" +
      "ument\030\002 \003(\01325.org.jetbrains.kotlin.seria" +
      "lization.js.ast.Expression\022^\n\017inline_str",
      "ategy\030\003 \001(\01629.org.jetbrains.kotlin.seria" +
      "lization.js.ast.InlineStrategy:\nNOT_INLI" +
      "NE\"\242\001\n\rInstantiation\022H\n\tqualifier\030\001 \002(\0132" +
      "5.org.jetbrains.kotlin.serialization.js." +
      "ast.Expression\022G\n\010argument\030\002 \003(\01325.org.j" +
      "etbrains.kotlin.serialization.js.ast.Exp" +
      "ression\"\323\013\n\tStatement\022\016\n\006fileId\030\001 \001(\005\022E\n" +
      "\010location\030\002 \001(\01323.org.jetbrains.kotlin.s" +
      "erialization.js.ast.Location\022\030\n\tsyntheti" +
      "c\030\003 \001(\010:\005false\022M\n\020return_statement\030\025 \001(\013",
      "21.org.jetbrains.kotlin.serialization.js" +
      ".ast.ReturnH\000\022K\n\017throw_statement\030\026 \001(\01320" +
      ".org.jetbrains.kotlin.serialization.js.a" +
      "st.ThrowH\000\022K\n\017break_statement\030\027 \001(\01320.or" +
      "g.jetbrains.kotlin.serialization.js.ast." +
      "BreakH\000\022Q\n\022continue_statement\030\030 \001(\01323.or" +
      "g.jetbrains.kotlin.serialization.js.ast." +
      "ContinueH\000\022G\n\010debugger\030\031 \001(\01323.org.jetbr" +
      "ains.kotlin.serialization.js.ast.Debugge" +
      "rH\000\022T\n\nexpression\030\032 \001(\0132>.org.jetbrains.",
      "kotlin.serialization.js.ast.ExpressionSt" +
      "atementH\000\022?\n\004vars\030\033 \001(\0132/.org.jetbrains." +
      "kotlin.serialization.js.ast.VarsH\000\022A\n\005bl" +
      "ock\030\034 \001(\01320.org.jetbrains.kotlin.seriali" +
      "zation.js.ast.BlockH\000\022N\n\014global_block\030\035 " +
      "\001(\01326.org.jetbrains.kotlin.serialization" +
      ".js.ast.GlobalBlockH\000\022A\n\005label\030\036 \001(\01320.o" +
      "rg.jetbrains.kotlin.serialization.js.ast" +
      ".LabelH\000\022E\n\014if_statement\030\037 \001(\0132-.org.jet" +
      "brains.kotlin.serialization.js.ast.IfH\000\022",
      "M\n\020switch_statement\030  \001(\01321.org.jetbrain" +
      "s.kotlin.serialization.js.ast.SwitchH\000\022K" +
      "\n\017while_statement\030! \001(\01320.org.jetbrains." +
      "kotlin.serialization.js.ast.WhileH\000\022P\n\022d" +
      "o_while_statement\030\" \001(\01322.org.jetbrains." +
      "kotlin.serialization.js.ast.DoWhileH\000\022G\n" +
      "\rfor_statement\030# \001(\0132..org.jetbrains.kot" +
      "lin.serialization.js.ast.ForH\000\022L\n\020for_in" +
      "_statement\030$ \001(\01320.org.jetbrains.kotlin." +
      "serialization.js.ast.ForInH\000\022G\n\rtry_stat",
      "ement\030% \001(\0132..org.jetbrains.kotlin.seria" +
      "lization.js.ast.TryH\000\022A\n\005empty\030& \001(\01320.o" +
      "rg.jetbrains.kotlin.serialization.js.ast" +
      ".EmptyH\000B\013\n\tstatement\"N\n\006Return\022D\n\005value" +
      "\030\001 \001(\01325.org.jetbrains.kotlin.serializat" +
      "ion.js.ast.Expression\"Q\n\005Throw\022H\n\texcept" +
      "ion\030\001 \002(\01325.org.jetbrains.kotlin.seriali" +
      "zation.js.ast.Expression\"\031\n\005Break\022\020\n\010lab" +
      "el_id\030\001 \001(\005\"\034\n\010Continue\022\020\n\010label_id\030\001 \001(" +
      "\005\"\n\n\010Debugger\"y\n\023ExpressionStatement\022I\n\n",
      "expression\030\001 \002(\01325.org.jetbrains.kotlin." +
      "serialization.js.ast.Expression\022\027\n\017expor" +
      "ted_tag_id\030\002 \001(\005\"\215\001\n\004Vars\022N\n\013declaration" +
      "\030\001 \003(\01329.org.jetbrains.kotlin.serializat" +
      "ion.js.ast.VarDeclaration\022\030\n\tmultiline\030\002" +
      " \001(\010:\005false\022\033\n\023exported_package_id\030\003 \001(\005" +
      "\"\306\001\n\016VarDeclaration\022\017\n\007name_id\030\001 \002(\005\022L\n\r" +
      "initial_value\030\002 \001(\01325.org.jetbrains.kotl" +
      "in.serialization.js.ast.Expression\022\016\n\006fi" +
      "leId\030\003 \001(\005\022E\n\010location\030\004 \001(\01323.org.jetbr",
      "ains.kotlin.serialization.js.ast.Locatio" +
      "n\"P\n\005Block\022G\n\tstatement\030\001 \003(\01324.org.jetb" +
      "rains.kotlin.serialization.js.ast.Statem" +
      "ent\"V\n\013GlobalBlock\022G\n\tstatement\030\001 \003(\01324." +
      "org.jetbrains.kotlin.serialization.js.as" +
      "t.Statement\"f\n\005Label\022\016\n\006nameId\030\001 \002(\005\022M\n\017" +
      "inner_statement\030\002 \002(\01324.org.jetbrains.ko" +
      "tlin.serialization.js.ast.Statement\"\352\001\n\002" +
      "If\022H\n\tcondition\030\001 \002(\01325.org.jetbrains.ko" +
      "tlin.serialization.js.ast.Expression\022L\n\016",
      "then_statement\030\002 \002(\01324.org.jetbrains.kot" +
      "lin.serialization.js.ast.Statement\022L\n\016el" +
      "se_statement\030\003 \001(\01324.org.jetbrains.kotli" +
      "n.serialization.js.ast.Statement\"\232\001\n\006Swi" +
      "tch\022I\n\nexpression\030\001 \002(\01325.org.jetbrains." +
      "kotlin.serialization.js.ast.Expression\022E" +
      "\n\005entry\030\002 \003(\01326.org.jetbrains.kotlin.ser" +
      "ialization.js.ast.SwitchEntry\"\363\001\n\013Switch" +
      "Entry\022D\n\005label\030\001 \001(\01325.org.jetbrains.kot" +
      "lin.serialization.js.ast.Expression\022G\n\ts",
      "tatement\030\002 \003(\01324.org.jetbrains.kotlin.se" +
      "rialization.js.ast.Statement\022\016\n\006fileId\030\003" +
      " \001(\005\022E\n\010location\030\004 \001(\01323.org.jetbrains.k" +
      "otlin.serialization.js.ast.Location\"\225\001\n\005" +
      "While\022H\n\tcondition\030\001 \002(\01325.org.jetbrains" +
      ".kotlin.serialization.js.ast.Expression\022" +
      "B\n\004body\030\002 \002(\01324.org.jetbrains.kotlin.ser" +
      "ialization.js.ast.Statement\"\227\001\n\007DoWhile\022" +
      "H\n\tcondition\030\001 \002(\01325.org.jetbrains.kotli" +
      "n.serialization.js.ast.Expression\022B\n\004bod",
      "y\030\002 \002(\01324.org.jetbrains.kotlin.serializa" +
      "tion.js.ast.Statement\"\304\003\n\003For\022I\n\tvariabl" +
      "es\030\001 \001(\01324.org.jetbrains.kotlin.serializ" +
      "ation.js.ast.StatementH\000\022K\n\nexpression\030\002" +
      " \001(\01325.org.jetbrains.kotlin.serializatio" +
      "n.js.ast.ExpressionH\000\022E\n\005empty\030\003 \001(\01324.o" +
      "rg.jetbrains.kotlin.serialization.js.ast" +
      ".EmptyInitH\000\022H\n\tcondition\030\004 \001(\01325.org.je" +
      "tbrains.kotlin.serialization.js.ast.Expr" +
      "ession\022H\n\tincrement\030\005 \001(\01325.org.jetbrain",
      "s.kotlin.serialization.js.ast.Expression" +
      "\022B\n\004body\030\006 \002(\01324.org.jetbrains.kotlin.se" +
      "rialization.js.ast.StatementB\006\n\004init\"\013\n\t" +
      "EmptyInit\"\374\001\n\005ForIn\022\020\n\006nameId\030\001 \001(\005H\000\022K\n" +
      "\nexpression\030\002 \001(\01325.org.jetbrains.kotlin" +
      ".serialization.js.ast.ExpressionH\000\022G\n\010it" +
      "erable\030\003 \002(\01325.org.jetbrains.kotlin.seri" +
      "alization.js.ast.Expression\022B\n\004body\030\004 \002(" +
      "\01324.org.jetbrains.kotlin.serialization.j" +
      "s.ast.StatementB\007\n\005value\"\337\001\n\003Try\022F\n\010tryB",
      "lock\030\001 \002(\01324.org.jetbrains.kotlin.serial" +
      "ization.js.ast.Statement\022D\n\ncatchBlock\030\002" +
      " \001(\01320.org.jetbrains.kotlin.serializatio" +
      "n.js.ast.Catch\022J\n\014finallyBlock\030\003 \001(\01324.o" +
      "rg.jetbrains.kotlin.serialization.js.ast" +
      ".Statement\"\224\001\n\005Catch\022G\n\tparameter\030\001 \002(\0132" +
      "4.org.jetbrains.kotlin.serialization.js." +
      "ast.Parameter\022B\n\004body\030\002 \002(\01324.org.jetbra" +
      "ins.kotlin.serialization.js.ast.Statemen" +
      "t\"\007\n\005Empty\"\327\005\n\010Fragment\022R\n\017imported_modu",
      "le\030\001 \003(\01329.org.jetbrains.kotlin.serializ" +
      "ation.js.ast.ImportedModule\022G\n\014import_en" +
      "try\030\002 \003(\01321.org.jetbrains.kotlin.seriali" +
      "zation.js.ast.Import\022Q\n\021declaration_bloc" +
      "k\030\003 \001(\01326.org.jetbrains.kotlin.serializa" +
      "tion.js.ast.GlobalBlock\022L\n\014export_block\030" +
      "\004 \001(\01326.org.jetbrains.kotlin.serializati" +
      "on.js.ast.GlobalBlock\022Q\n\021initializer_blo" +
      "ck\030\005 \001(\01326.org.jetbrains.kotlin.serializ" +
      "ation.js.ast.GlobalBlock\022L\n\014name_binding",
      "\030\006 \003(\01326.org.jetbrains.kotlin.serializat" +
      "ion.js.ast.NameBinding\022J\n\013class_model\030\007 " +
      "\003(\01325.org.jetbrains.kotlin.serialization" +
      ".js.ast.ClassModel\022P\n\021module_expression\030" +
      "\010 \003(\01325.org.jetbrains.kotlin.serializati" +
      "on.js.ast.Expression\022N\n\rinline_module\030\t " +
      "\003(\01327.org.jetbrains.kotlin.serialization" +
      ".js.ast.InlineModule\"\224\001\n\016ImportedModule\022" +
      "\030\n\020external_name_id\030\001 \002(\005\022\030\n\020internal_na" +
      "me_id\030\002 \002(\005\022N\n\017plain_reference\030\003 \001(\01325.o",
      "rg.jetbrains.kotlin.serialization.js.ast" +
      ".Expression\"i\n\006Import\022\024\n\014signature_id\030\001 " +
      "\002(\005\022I\n\nexpression\030\002 \002(\01325.org.jetbrains." +
      "kotlin.serialization.js.ast.Expression\"3" +
      "\n\013NameBinding\022\024\n\014signature_id\030\001 \002(\005\022\016\n\006n" +
      "ameId\030\002 \002(\005\"\247\001\n\nClassModel\022\017\n\007name_id\030\001 " +
      "\002(\005\022\025\n\rsuper_name_id\030\002 \001(\005\022\031\n\021interface_" +
      "name_id\030\004 \003(\005\022V\n\026post_declaration_block\030" +
      "\003 \001(\01326.org.jetbrains.kotlin.serializati" +
      "on.js.ast.GlobalBlock\";\n\014InlineModule\022\024\n",
      "\014signature_id\030\001 \002(\005\022\025\n\rexpression_id\030\002 \002" +
      "(\005\"\034\n\013StringTable\022\r\n\005entry\030\001 \003(\t\"K\n\tName" +
      "Table\022>\n\005entry\030\001 \003(\0132/.org.jetbrains.kot" +
      "lin.serialization.js.ast.Name\"\263\001\n\004Name\022\021" +
      "\n\ttemporary\030\001 \002(\010\022\022\n\nidentifier\030\002 \001(\005\022\025\n" +
      "\rlocal_name_id\030\003 \001(\005\022\027\n\010imported\030\004 \001(\010:\005" +
      "false\022T\n\020special_function\030\005 \001(\0162:.org.je" +
      "tbrains.kotlin.serialization.js.ast.Spec" +
      "ialFunction\"\346\001\n\005Chunk\022L\n\014string_table\030\001 " +
      "\002(\01326.org.jetbrains.kotlin.serialization",
      ".js.ast.StringTable\022H\n\nname_table\030\002 \002(\0132" +
      "4.org.jetbrains.kotlin.serialization.js." +
      "ast.NameTable\022E\n\010fragment\030\003 \002(\01323.org.je" +
      "tbrains.kotlin.serialization.js.ast.Frag" +
      "ment*@\n\013SideEffects\022\021\n\rAFFECTS_STATE\020\001\022\024" +
      "\n\020DEPENDS_ON_STATE\020\002\022\010\n\004PURE\020\003*?\n\016Inline" +
      "Strategy\022\017\n\013AS_FUNCTION\020\000\022\014\n\010IN_PLACE\020\001\022" +
      "\016\n\nNOT_INLINE\020\002*\327\001\n\017SpecialFunction\022\032\n\026D" +
      "EFINE_INLINE_FUNCTION\020\001\022\021\n\rWRAP_FUNCTION" +
      "\020\002\022\021\n\rTO_BOXED_CHAR\020\003\022\016\n\nUNBOX_CHAR\020\004\022\020\n",
      "\014SUSPEND_CALL\020\005\022\024\n\020COROUTINE_RESULT\020\006\022\030\n" +
      "\024COROUTINE_CONTROLLER\020\007\022\026\n\022COROUTINE_REC" +
      "EIVER\020\010\022\030\n\024SET_COROUTINE_RESULT\020\tB\024B\022Deb" +
      "ugJsAstProtoBuf"
    };
    org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
        new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
          public org.jetbrains.kotlin.protobuf.ExtensionRegistry assignDescriptors(
              org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor root) {
            descriptor = root;
            return null;
          }
        };
    org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Location_descriptor,
        new java.lang.String[] { "StartLine", "StartChar", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Expression_descriptor,
        new java.lang.String[] { "FileId", "Location", "Synthetic", "SideEffects", "LocalAlias", "SimpleNameReference", "ThisLiteral", "NullLiteral", "TrueLiteral", "FalseLiteral", "StringLiteral", "RegExpLiteral", "IntLiteral", "DoubleLiteral", "ArrayLiteral", "ObjectLiteral", "Function", "DocComment", "Binary", "Unary", "Conditional", "ArrayAccess", "NameReference", "PropertyReference", "Invocation", "Instantiation", "Expression", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ThisLiteral_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_NullLiteral_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_descriptor =
      getDescriptor().getMessageTypes().get(4);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_TrueLiteral_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_descriptor =
      getDescriptor().getMessageTypes().get(5);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_FalseLiteral_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_descriptor =
      getDescriptor().getMessageTypes().get(6);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_RegExpLiteral_descriptor,
        new java.lang.String[] { "PatternStringId", "FlagsStringId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_descriptor =
      getDescriptor().getMessageTypes().get(7);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayLiteral_descriptor,
        new java.lang.String[] { "Element", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_descriptor =
      getDescriptor().getMessageTypes().get(8);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteral_descriptor,
        new java.lang.String[] { "Entry", "Multiline", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_descriptor =
      getDescriptor().getMessageTypes().get(9);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ObjectLiteralEntry_descriptor,
        new java.lang.String[] { "Key", "Value", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_descriptor =
      getDescriptor().getMessageTypes().get(10);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Function_descriptor,
        new java.lang.String[] { "Parameter", "NameId", "Body", "Local", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_descriptor =
      getDescriptor().getMessageTypes().get(11);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Parameter_descriptor,
        new java.lang.String[] { "NameId", "HasDefaultValue", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_descriptor =
      getDescriptor().getMessageTypes().get(12);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_DocComment_descriptor,
        new java.lang.String[] { "Tag", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_descriptor =
      getDescriptor().getMessageTypes().get(13);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_DocCommentTag_descriptor,
        new java.lang.String[] { "NameId", "ValueStringId", "Expression", "Value", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_descriptor =
      getDescriptor().getMessageTypes().get(14);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_BinaryOperation_descriptor,
        new java.lang.String[] { "Left", "Right", "Type", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_descriptor =
      getDescriptor().getMessageTypes().get(15);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_UnaryOperation_descriptor,
        new java.lang.String[] { "Operand", "Type", "Postfix", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_descriptor =
      getDescriptor().getMessageTypes().get(16);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Conditional_descriptor,
        new java.lang.String[] { "TestExpression", "ThenExpression", "ElseExpression", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_descriptor =
      getDescriptor().getMessageTypes().get(17);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ArrayAccess_descriptor,
        new java.lang.String[] { "Array", "Index", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_descriptor =
      getDescriptor().getMessageTypes().get(18);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_NameReference_descriptor,
        new java.lang.String[] { "NameId", "Qualifier", "InlineStrategy", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_descriptor =
      getDescriptor().getMessageTypes().get(19);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_PropertyReference_descriptor,
        new java.lang.String[] { "StringId", "Qualifier", "InlineStrategy", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_descriptor =
      getDescriptor().getMessageTypes().get(20);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Invocation_descriptor,
        new java.lang.String[] { "Qualifier", "Argument", "InlineStrategy", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_descriptor =
      getDescriptor().getMessageTypes().get(21);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Instantiation_descriptor,
        new java.lang.String[] { "Qualifier", "Argument", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_descriptor =
      getDescriptor().getMessageTypes().get(22);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Statement_descriptor,
        new java.lang.String[] { "FileId", "Location", "Synthetic", "ReturnStatement", "ThrowStatement", "BreakStatement", "ContinueStatement", "Debugger", "Expression", "Vars", "Block", "GlobalBlock", "Label", "IfStatement", "SwitchStatement", "WhileStatement", "DoWhileStatement", "ForStatement", "ForInStatement", "TryStatement", "Empty", "Statement", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_descriptor =
      getDescriptor().getMessageTypes().get(23);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Return_descriptor,
        new java.lang.String[] { "Value", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_descriptor =
      getDescriptor().getMessageTypes().get(24);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Throw_descriptor,
        new java.lang.String[] { "Exception", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_descriptor =
      getDescriptor().getMessageTypes().get(25);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Break_descriptor,
        new java.lang.String[] { "LabelId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_descriptor =
      getDescriptor().getMessageTypes().get(26);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Continue_descriptor,
        new java.lang.String[] { "LabelId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_descriptor =
      getDescriptor().getMessageTypes().get(27);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Debugger_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_descriptor =
      getDescriptor().getMessageTypes().get(28);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ExpressionStatement_descriptor,
        new java.lang.String[] { "Expression", "ExportedTagId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_descriptor =
      getDescriptor().getMessageTypes().get(29);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Vars_descriptor,
        new java.lang.String[] { "Declaration", "Multiline", "ExportedPackageId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_descriptor =
      getDescriptor().getMessageTypes().get(30);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_VarDeclaration_descriptor,
        new java.lang.String[] { "NameId", "InitialValue", "FileId", "Location", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_descriptor =
      getDescriptor().getMessageTypes().get(31);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Block_descriptor,
        new java.lang.String[] { "Statement", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_descriptor =
      getDescriptor().getMessageTypes().get(32);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_GlobalBlock_descriptor,
        new java.lang.String[] { "Statement", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_descriptor =
      getDescriptor().getMessageTypes().get(33);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Label_descriptor,
        new java.lang.String[] { "NameId", "InnerStatement", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_If_descriptor =
      getDescriptor().getMessageTypes().get(34);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_If_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_If_descriptor,
        new java.lang.String[] { "Condition", "ThenStatement", "ElseStatement", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_descriptor =
      getDescriptor().getMessageTypes().get(35);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Switch_descriptor,
        new java.lang.String[] { "Expression", "Entry", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor =
      getDescriptor().getMessageTypes().get(36);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_SwitchEntry_descriptor,
        new java.lang.String[] { "Label", "Statement", "FileId", "Location", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor =
      getDescriptor().getMessageTypes().get(37);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_While_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_While_descriptor,
        new java.lang.String[] { "Condition", "Body", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_descriptor =
      getDescriptor().getMessageTypes().get(38);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_DoWhile_descriptor,
        new java.lang.String[] { "Condition", "Body", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_For_descriptor =
      getDescriptor().getMessageTypes().get(39);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_For_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_For_descriptor,
        new java.lang.String[] { "Variables", "Expression", "Empty", "Condition", "Increment", "Body", "Init", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_descriptor =
      getDescriptor().getMessageTypes().get(40);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_EmptyInit_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_descriptor =
      getDescriptor().getMessageTypes().get(41);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ForIn_descriptor,
        new java.lang.String[] { "NameId", "Expression", "Iterable", "Body", "Value", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_descriptor =
      getDescriptor().getMessageTypes().get(42);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Try_descriptor,
        new java.lang.String[] { "TryBlock", "CatchBlock", "FinallyBlock", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_descriptor =
      getDescriptor().getMessageTypes().get(43);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Catch_descriptor,
        new java.lang.String[] { "Parameter", "Body", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_descriptor =
      getDescriptor().getMessageTypes().get(44);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Empty_descriptor,
        new java.lang.String[] { });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_descriptor =
      getDescriptor().getMessageTypes().get(45);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Fragment_descriptor,
        new java.lang.String[] { "ImportedModule", "ImportEntry", "DeclarationBlock", "ExportBlock", "InitializerBlock", "NameBinding", "ClassModel", "ModuleExpression", "InlineModule", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_descriptor =
      getDescriptor().getMessageTypes().get(46);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ImportedModule_descriptor,
        new java.lang.String[] { "ExternalNameId", "InternalNameId", "PlainReference", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_descriptor =
      getDescriptor().getMessageTypes().get(47);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Import_descriptor,
        new java.lang.String[] { "SignatureId", "Expression", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_descriptor =
      getDescriptor().getMessageTypes().get(48);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_NameBinding_descriptor,
        new java.lang.String[] { "SignatureId", "NameId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor =
      getDescriptor().getMessageTypes().get(49);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_ClassModel_descriptor,
        new java.lang.String[] { "NameId", "SuperNameId", "InterfaceNameId", "PostDeclarationBlock", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor =
      getDescriptor().getMessageTypes().get(50);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_InlineModule_descriptor,
        new java.lang.String[] { "SignatureId", "ExpressionId", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_descriptor =
      getDescriptor().getMessageTypes().get(51);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_StringTable_descriptor,
        new java.lang.String[] { "Entry", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_descriptor =
      getDescriptor().getMessageTypes().get(52);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_NameTable_descriptor,
        new java.lang.String[] { "Entry", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_descriptor =
      getDescriptor().getMessageTypes().get(53);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Name_descriptor,
        new java.lang.String[] { "Temporary", "Identifier", "LocalNameId", "Imported", "SpecialFunction", });
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_descriptor =
      getDescriptor().getMessageTypes().get(54);
    internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_fieldAccessorTable = new
      org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
        internal_static_org_jetbrains_kotlin_serialization_js_ast_Chunk_descriptor,
        new java.lang.String[] { "StringTable", "NameTable", "Fragment", });
  }

  // @@protoc_insertion_point(outer_class_scope)
}