<?php

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

namespace RocketMQ;

class MessageExt{

	public function parseTopicFilterType(int $parseTopicFilterType){
	}
	public function getQueue(){
	}
	public function setQueueId(int $setQueueid){
	}
	public function getBornTimestamp(){
	}
	public function setBornTimestamp(int $bornTimestamp){
	}
	public function getStoreHostString(){
	}
	public function getMsgId(){
	}
	public function setMsgId(string $msgId){
	}
	public function getOffsetMsgId(){
	}
	public function setOffsetMsgId(int $offsetMsgId){
	}
	public function getBodyCRC(){
	}
	public function setBodyCRC(int $bodyCRC){
	}
	public function getQueueOffset(){
	}
	public function setQueueOffset(int $queueOffset){
	}
	public function getCommitLogOffset(){
	}
	public function setCommitLogOffset(int $physicOffset){
	}
	public function getStoreSize(){
	}
	public function setStoreSize(int $storeSize){
	}
	public function getReconsumeTimes(){
	}
	public function getPreparedTransactionOffset(){
	}
	public function setPreparedTransactionOffset(int $preparedTransactionOffset){
	}
	public function toString(){
	}
	public function getMessage(){
	}
}
