1 /*-------------------------------------------------------------------------
2  *
3  * jsonapi.h
4  *	  Declarations for JSON API support.
5  *
6  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * src/include/utils/jsonapi.h
10  *
11  *-------------------------------------------------------------------------
12  */
13 
14 #ifndef JSONAPI_H
15 #define JSONAPI_H
16 
17 #include "lib/stringinfo.h"
18 
19 typedef enum
20 {
21 	JSON_TOKEN_INVALID,
22 	JSON_TOKEN_STRING,
23 	JSON_TOKEN_NUMBER,
24 	JSON_TOKEN_OBJECT_START,
25 	JSON_TOKEN_OBJECT_END,
26 	JSON_TOKEN_ARRAY_START,
27 	JSON_TOKEN_ARRAY_END,
28 	JSON_TOKEN_COMMA,
29 	JSON_TOKEN_COLON,
30 	JSON_TOKEN_TRUE,
31 	JSON_TOKEN_FALSE,
32 	JSON_TOKEN_NULL,
33 	JSON_TOKEN_END
34 } JsonTokenType;
35 
36 typedef enum
37 {
38 	JSON_SUCCESS,
39 	JSON_ESCAPING_INVALID,
40 	JSON_ESCAPING_REQUIRED,
41 	JSON_EXPECTED_ARRAY_FIRST,
42 	JSON_EXPECTED_ARRAY_NEXT,
43 	JSON_EXPECTED_COLON,
44 	JSON_EXPECTED_END,
45 	JSON_EXPECTED_JSON,
46 	JSON_EXPECTED_MORE,
47 	JSON_EXPECTED_OBJECT_FIRST,
48 	JSON_EXPECTED_OBJECT_NEXT,
49 	JSON_EXPECTED_STRING,
50 	JSON_INVALID_TOKEN,
51 	JSON_UNICODE_CODE_POINT_ZERO,
52 	JSON_UNICODE_ESCAPE_FORMAT,
53 	JSON_UNICODE_HIGH_ESCAPE,
54 	JSON_UNICODE_HIGH_SURROGATE,
55 	JSON_UNICODE_LOW_SURROGATE
56 } JsonParseErrorType;
57 
58 
59 /*
60  * All the fields in this structure should be treated as read-only.
61  *
62  * If strval is not null, then it should contain the de-escaped value
63  * of the lexeme if it's a string. Otherwise most of these field names
64  * should be self-explanatory.
65  *
66  * line_number and line_start are principally for use by the parser's
67  * error reporting routines.
68  * token_terminator and prev_token_terminator point to the character
69  * AFTER the end of the token, i.e. where there would be a nul byte
70  * if we were using nul-terminated strings.
71  */
72 typedef struct JsonLexContext
73 {
74 	char	   *input;
75 	int			input_length;
76 	int			input_encoding;
77 	char	   *token_start;
78 	char	   *token_terminator;
79 	char	   *prev_token_terminator;
80 	JsonTokenType token_type;
81 	int			lex_level;
82 	int			line_number;
83 	char	   *line_start;
84 	StringInfo	strval;
85 } JsonLexContext;
86 
87 typedef void (*json_struct_action) (void *state);
88 typedef void (*json_ofield_action) (void *state, char *fname, bool isnull);
89 typedef void (*json_aelem_action) (void *state, bool isnull);
90 typedef void (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype);
91 
92 
93 /*
94  * Semantic Action structure for use in parsing json.
95  * Any of these actions can be NULL, in which case nothing is done at that
96  * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts
97  * to doing a pure parse with no side-effects, and is therefore exactly
98  * what the json input routines do.
99  *
100  * The 'fname' and 'token' strings passed to these actions are palloc'd.
101  * They are not free'd or used further by the parser, so the action function
102  * is free to do what it wishes with them.
103  */
104 typedef struct JsonSemAction
105 {
106 	void	   *semstate;
107 	json_struct_action object_start;
108 	json_struct_action object_end;
109 	json_struct_action array_start;
110 	json_struct_action array_end;
111 	json_ofield_action object_field_start;
112 	json_ofield_action object_field_end;
113 	json_aelem_action array_element_start;
114 	json_aelem_action array_element_end;
115 	json_scalar_action scalar;
116 } JsonSemAction;
117 
118 /*
119  * pg_parse_json will parse the string in the lex calling the
120  * action functions in sem at the appropriate points. It is
121  * up to them to keep what state they need	in semstate. If they
122  * need access to the state of the lexer, then its pointer
123  * should be passed to them as a member of whatever semstate
124  * points to. If the action pointers are NULL the parser
125  * does nothing and just continues.
126  */
127 extern JsonParseErrorType pg_parse_json(JsonLexContext *lex,
128 										JsonSemAction *sem);
129 
130 /* the null action object used for pure validation */
131 extern JsonSemAction nullSemAction;
132 
133 /*
134  * json_count_array_elements performs a fast secondary parse to determine the
135  * number of elements in passed array lex context. It should be called from an
136  * array_start action.
137  *
138  * The return value indicates whether any error occurred, while the number
139  * of elements is stored into *elements (but only if the return value is
140  * JSON_SUCCESS).
141  */
142 extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex,
143 													int *elements);
144 
145 /*
146  * constructor for JsonLexContext, with or without strval element.
147  * If supplied, the strval element will contain a de-escaped version of
148  * the lexeme. However, doing this imposes a performance penalty, so
149  * it should be avoided if the de-escaped lexeme is not required.
150  */
151 extern JsonLexContext *makeJsonLexContextCstringLen(char *json,
152 													int len,
153 													int encoding,
154 													bool need_escapes);
155 
156 /* lex one token */
157 extern JsonParseErrorType json_lex(JsonLexContext *lex);
158 
159 /* construct an error detail string for a json error */
160 extern char *json_errdetail(JsonParseErrorType error, JsonLexContext *lex);
161 
162 /*
163  * Utility function to check if a string is a valid JSON number.
164  *
165  * str argument does not need to be nul-terminated.
166  */
167 extern bool IsValidJsonNumber(const char *str, int len);
168 
169 #endif							/* JSONAPI_H */
170