blob: d1785537bdd9274940836a30be947b418369f4ef [file]
// Copyright 2023 Google LLC
//
// Licensed 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
//
// https://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.
#ifndef MPACT_SIM_DECODER_PROTO_INSTRUCTION_GROUP_H_
#define MPACT_SIM_DECODER_PROTO_INSTRUCTION_GROUP_H_
#include <string>
#include <utility>
#include <vector>
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/decoder_error_listener.h"
#include "mpact/sim/decoder/proto_format_contexts.h"
#include "mpact/sim/decoder/proto_instruction_encoding.h"
#include "src/google/protobuf/descriptor.h"
namespace mpact {
namespace sim {
namespace decoder {
namespace proto_fmt {
class ProtoInstructionEncoding;
class ProtoEncodingInfo;
class ProtoEncodingGroup;
struct SetterInfo {
SetterDefCtx* ctx;
std::string name;
const google::protobuf::FieldDescriptor* field_desc;
std::vector<const google::protobuf::FieldDescriptor*> one_of_fields;
IfNotCtx* if_not;
};
// This class represents an instruction group from the .proto_fmt file.
class ProtoInstructionGroup {
public:
ProtoInstructionGroup(std::string group_name,
const google::protobuf::Descriptor* message_type,
std::string opcode_enum,
ProtoEncodingInfo* encoding_info);
ProtoInstructionGroup() = delete;
~ProtoInstructionGroup();
// Add group level setter.
absl::Status AddSetter(
const std::string& group_name, SetterDefCtx* ctx,
const std::string& setter_name,
const google::protobuf::FieldDescriptor* field_desc,
std::vector<const google::protobuf::FieldDescriptor*> one_of_fields,
IfNotCtx* if_not);
// Look up the setters in the named setter group. If found, return the begin
// and end iterators for those setters.
absl::StatusOr<
std::pair<absl::btree_map<std::string, SetterInfo*>::const_iterator,
absl::btree_map<std::string, SetterInfo*>::const_iterator>>
GetSetterGroup(absl::string_view group) const;
// Create and return an instruction encoding with the given name.
ProtoInstructionEncoding* AddInstructionEncoding(std::string name);
// Create a copy of the given instruction encoding.
void CopyInstructionEncoding(ProtoInstructionEncoding* encoding);
// Create an encoding group for this instruction group and then subdivide
// it in a hierarchy as necessary.
void ProcessEncodings(DecoderErrorListener* error_listener);
// Generate the decoder for this instruction group.
std::string GenerateDecoder() const;
// Accessors.
const std::string& name() const { return name_; }
const google::protobuf::Descriptor* message_type() const {
return message_type_;
}
const std::vector<ProtoInstructionEncoding*>& encodings() const {
return encodings_;
}
const ProtoEncodingInfo* encoding_info() const { return encoding_info_; }
private:
std::string name_;
const google::protobuf::Descriptor* message_type_;
std::string opcode_enum_;
ProtoEncodingInfo* encoding_info_;
absl::flat_hash_set<std::string> encoding_name_set_;
std::vector<ProtoInstructionEncoding*> encodings_;
// Encoding group.
ProtoEncodingGroup* encoding_group_ = nullptr;
// Setter names and types.
absl::btree_map<std::string, int> setter_name_to_type_;
// Setter group map. Maps from setter group name to a map from setter name
// to setter info.
absl::btree_map<std::string, absl::btree_map<std::string, SetterInfo*>>
setter_groups_;
};
} // namespace proto_fmt
} // namespace decoder
} // namespace sim
} // namespace mpact
#endif // MPACT_SIM_DECODER_PROTO_INSTRUCTION_GROUP_H_