code: @Override
      public TMessage readMessageBegin() throws TException {
          root = null;
          try {
              readRoot();
          } catch (IOException e) {
              throw new TException("Could not parse input, is it valid json?", e);
          }
          if (!root.isObject()) {
              throw new TException("The top level of the input must be a json object with method and args!");
          }
  
          if (!root.has("method")) {
              throw new TException("Object must have field 'method' with the rpc method name!");
          }
          final String methodName = root.get("method").asText();
  
          if (!root.has("type")) {
              throw new TException(
                      "Object must have field 'type' with the message type (CALL, REPLY, EXCEPTION, ONEWAY)!");
          }
          final Byte messageType = TypedParser.TMESSAGE_TYPE.readFromJsonElement(root.get("type"));
  
          if (!root.has("args") || !root.get("args").isObject()) {
              throw new TException("Object must have field 'args' with the rpc method args!");
          }
  
          final int sequenceId = root.has("seqid") ? root.get("seqid").asInt() : 0;
  
          // Override the root with the content of args - thrift's rpc reading will
          // proceed to read it as a message object.
          root = root.get("args");
  
          return new TMessage(methodName, messageType, sequenceId);
      }
docs: ///////////////////////////////////////