3030#include " p4/config/v1/p4info.pb.h"
3131#include " p4_constraints/ast.pb.h"
3232#include " p4_constraints/backend/type_checker.h"
33- #include " p4_constraints/constraint_source.h"
3433#include " p4_constraints/frontend/lexer.h"
3534#include " p4_constraints/frontend/parser.h"
3635#include " re2/re2.h"
@@ -42,7 +41,8 @@ namespace {
4241using p4::config::v1::MatchField;
4342using p4::config::v1::Table;
4443
45- absl::StatusOr<ConstraintSource> ExtractConstraint (const Table& table) {
44+ absl::StatusOr<absl::optional<ast::Expression>> ParseTableConstraint (
45+ const Table& table) {
4646 // We expect .p4 files to have the following format:
4747 // ```p4
4848 // @file(__FILE__) // optional
@@ -58,38 +58,38 @@ absl::StatusOr<ConstraintSource> ExtractConstraint(const Table& table) {
5858 const RE2 line_annotation = {R"RE( @line[(](\d+)[)])RE" };
5959 const RE2 constraint_annotation = {R"RE( @entry_restriction)RE" };
6060
61- absl::string_view constraint_string = " " ;
62- ast::SourceLocation constraint_location;
61+ ast::SourceLocation location;
6362 int line = 0 ;
63+ absl::string_view constraint = " " ;
6464 for (absl::string_view annotation : table.preamble ().annotations ()) {
6565 if (RE2::Consume (&annotation, file_annotation,
66- constraint_location .mutable_file_path ()))
66+ location .mutable_file_path ()))
6767 continue ;
6868 if (RE2::Consume (&annotation, line_annotation, &line)) continue ;
6969 if (RE2::Consume (&annotation, constraint_annotation)) {
70- constraint_string = annotation.data ();
70+ constraint = annotation.data ();
7171 break ;
7272 }
7373 }
74-
75- if (constraint_string.empty ()) return ConstraintSource ();
76-
77- constraint_location.set_line (line);
78- if (constraint_location.file_path ().empty ()) {
79- constraint_location.set_table_name (table.preamble ().name ());
74+ location.set_line (line);
75+ if (location.file_path ().empty ()) {
76+ location.set_table_name (table.preamble ().name ());
8077 }
8178
82- if (!absl::ConsumePrefix (&constraint_string, " (\" " ) ||
83- !absl::ConsumeSuffix (&constraint_string, " \" )" )) {
79+ if (constraint.empty ()) {
80+ return absl::optional<ast::Expression>();
81+ }
82+ if (!absl::ConsumePrefix (&constraint, " (\" " ) ||
83+ !absl::ConsumeSuffix (&constraint, " \" )" )) {
8484 return gutils::InvalidArgumentErrorBuilder (GUTILS_LOC)
8585 << " In table " << table.preamble ().name () << " :\n "
8686 << " Syntax error: @entry_restriction must be enclosed in "
8787 " '(\" ' and '\" )'" ;
8888 }
89- return ConstraintSource{
90- . constraint_string = std::string (constraint_string),
91- . constraint_location = constraint_location,
92- } ;
89+ // TODO(smolkaj): With C++17, we can use std::string_view throughout and
90+ // won't need to make an extra copy here.
91+ const auto constraint_str = std::string (constraint);
92+ return ParseConstraint ( Tokenize (constraint_str, location)) ;
9393}
9494
9595absl::StatusOr<ast::Type> ParseKeyType (const MatchField& key) {
@@ -145,26 +145,14 @@ absl::StatusOr<TableInfo> ParseTableInfo(const Table& table) {
145145 }
146146 }
147147
148- ASSIGN_OR_RETURN (ConstraintSource constraint_source,
149- ExtractConstraint (table));
150-
151- absl::optional<ast::Expression> constraint = absl::nullopt ;
152- if (!constraint_source.constraint_string .empty ()) {
153- ASSIGN_OR_RETURN (constraint, ParseConstraint (Tokenize (
154- constraint_source.constraint_string ,
155- constraint_source.constraint_location )));
156- }
157-
158- TableInfo table_info{
159- .id = table.preamble ().id (),
160- .name = table.preamble ().name (),
161- .constraint = constraint,
162- .constraint_source = constraint_source,
163- .keys_by_id = keys_by_id,
164- .keys_by_name = keys_by_name,
165- };
148+ TableInfo table_info{.id = table.preamble ().id (),
149+ .name = table.preamble ().name (),
150+ .constraint = {}, // Inserted in a second.
151+ .keys_by_id = keys_by_id,
152+ .keys_by_name = keys_by_name};
166153
167- // Type check constraint.
154+ // Parse and type check constraint.
155+ ASSIGN_OR_RETURN (table_info.constraint , ParseTableConstraint (table));
168156 if (table_info.constraint .has_value ()) {
169157 RETURN_IF_ERROR (
170158 InferAndCheckTypes (&table_info.constraint .value (), table_info));
0 commit comments